1. Project Clover database Sat Apr 27 2024 21:29:13 CDT
  2. Package net.bytebuddy.dynamic

File DynamicType.java

 

Coverage histogram

../../../img/srcFileCovDistChart9.png
81% of files have more coverage

Code metrics

52
468
279
57
4,477
2,074
310
0.66
1.68
4.89
1.11

Classes

Class Line # Actions
DynamicType 46 0 - 0 0
-1.0 -
DynamicType.Builder 181 0 - 0 0
-1.0 -
DynamicType.Builder.TypeVariableDefinition 831 0 - 0 0
-1.0 -
DynamicType.Builder.TypeVariableDefinition.AbstractBase 874 3 0% 3 4
0.3333333433.3%
DynamicType.Builder.FieldDefinition 898 0 - 0 0
-1.0 -
DynamicType.Builder.FieldDefinition.Valuable 961 0 - 0 0
-1.0 -
DynamicType.Builder.FieldDefinition.Optional 1070 0 - 0 0
-1.0 -
DynamicType.Builder.FieldDefinition.Optional.Valuable 1077 0 - 0 0
-1.0 -
DynamicType.Builder.FieldDefinition.Optional.Valuable.AbstractBase 1084 8 0% 8 1
0.944444494.4%
DynamicType.Builder.FieldDefinition.Optional.Valuable.AbstractBase.Adapter 1133 16 0% 11 4
0.866666786.7%
DynamicType.Builder.FieldDefinition.Optional.AbstractBase 1214 3 0% 3 0
1.0100%
DynamicType.Builder.MethodDefinition 1239 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.ReceiverTypeDefinition 1342 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.ReceiverTypeDefinition.AbstractBase 1367 1 0% 1 2
0.00%
DynamicType.Builder.MethodDefinition.ImplementationDefinition 1381 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.ImplementationDefinition.Optional 1437 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.ImplementationDefinition.AbstractBase 1446 1 0% 1 0
1.0100%
DynamicType.Builder.MethodDefinition.TypeVariableDefinition 1460 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.TypeVariableDefinition.Annotatable 1515 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.TypeVariableDefinition.Annotatable.AbstractBase 1558 3 0% 3 4
0.3333333433.3%
DynamicType.Builder.MethodDefinition.TypeVariableDefinition.Annotatable.AbstractBase.Adapter 1580 5 0% 5 4
0.660%
DynamicType.Builder.MethodDefinition.TypeVariableDefinition.AbstractBase 1623 4 0% 4 0
1.0100%
DynamicType.Builder.MethodDefinition.ExceptionDefinition 1652 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.ExceptionDefinition.AbstractBase 1691 3 0% 3 0
1.0100%
DynamicType.Builder.MethodDefinition.ParameterDefinition 1715 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.ParameterDefinition.Annotatable 1788 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.ParameterDefinition.Annotatable.AbstractBase 1831 3 0% 3 6
0.00%
DynamicType.Builder.MethodDefinition.ParameterDefinition.Annotatable.AbstractBase.Adapter 1853 7 0% 7 12
0.1428571514.3%
DynamicType.Builder.MethodDefinition.ParameterDefinition.Simple 1905 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.ParameterDefinition.Simple.Annotatable 1930 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.ParameterDefinition.Simple.Annotatable.AbstractBase 1973 3 0% 3 6
0.00%
DynamicType.Builder.MethodDefinition.ParameterDefinition.Simple.Annotatable.AbstractBase.Adapter 1995 7 0% 7 6
0.571428657.1%
DynamicType.Builder.MethodDefinition.ParameterDefinition.Simple.AbstractBase 2047 1 0% 1 2
0.00%
DynamicType.Builder.MethodDefinition.ParameterDefinition.Initial 2064 0 - 0 0
-1.0 -
DynamicType.Builder.MethodDefinition.ParameterDefinition.Initial.AbstractBase 2107 8 0% 5 2
0.8461538684.6%
DynamicType.Builder.MethodDefinition.ParameterDefinition.AbstractBase 2145 5 0% 5 4
0.660%
DynamicType.Builder.MethodDefinition.AbstractBase 2179 6 0% 6 6
0.550%
DynamicType.Builder.MethodDefinition.AbstractBase.Adapter 2216 15 0% 8 6
0.7575%
DynamicType.Builder.AbstractBase 2292 48 0% 38 26
0.7045454470.5%
DynamicType.Builder.AbstractBase.Delegator 2497 19 0% 19 16
0.5789473757.9%
DynamicType.Builder.AbstractBase.Adapter 2607 49 0% 22 8
0.888888988.9%
DynamicType.Builder.AbstractBase.Adapter.TypeVariableDefinitionAdapter 2981 9 0% 7 0
1.0100%
DynamicType.Builder.AbstractBase.Adapter.FieldDefinitionAdapter 3057 13 0% 9 0
1.0100%
DynamicType.Builder.AbstractBase.Adapter.FieldMatchAdapter 3162 13 0% 9 0
1.0100%
DynamicType.Builder.AbstractBase.Adapter.MethodDefinitionAdapter 3262 13 0% 13 0
1.0100%
DynamicType.Builder.AbstractBase.Adapter.MethodDefinitionAdapter.TypeVariableAnnotationAdapter 3380 7 0% 7 0
1.0100%
DynamicType.Builder.AbstractBase.Adapter.MethodDefinitionAdapter.ParameterAnnotationAdapter 3450 7 0% 7 2
0.8571428785.7%
DynamicType.Builder.AbstractBase.Adapter.MethodDefinitionAdapter.SimpleParameterAnnotationAdapter 3521 7 0% 7 2
0.8571428785.7%
DynamicType.Builder.AbstractBase.Adapter.MethodDefinitionAdapter.AnnotationAdapter 3592 13 0% 11 6
0.7575%
DynamicType.Builder.AbstractBase.Adapter.MethodMatchAdapter 3720 9 0% 9 0
1.0100%
DynamicType.Builder.AbstractBase.Adapter.MethodMatchAdapter.AnnotationAdapter 3794 11 0% 11 2
0.9090909490.9%
DynamicType.Builder.AbstractBase.Adapter.OptionalMethodMatchAdapter 3896 19 0% 14 6
0.823529482.4%
DynamicType.Loaded 4004 0 - 0 0
-1.0 -
DynamicType.Unloaded 4033 0 - 0 0
-1.0 -
DynamicType.Default 4065 111 0% 28 11
0.926666792.7%
DynamicType.Default.Unloaded 4348 9 0% 6 0
1.0100%
DynamicType.Default.Loaded 4415 9 0% 6 0
1.0100%
 

Contributing tests

This file is covered by 1169 tests. .

Source view

1    package net.bytebuddy.dynamic;
2   
3    import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
4    import net.bytebuddy.ClassFileVersion;
5    import net.bytebuddy.asm.AsmVisitorWrapper;
6    import net.bytebuddy.description.annotation.AnnotationDescription;
7    import net.bytebuddy.description.annotation.AnnotationList;
8    import net.bytebuddy.description.field.FieldDescription;
9    import net.bytebuddy.description.method.MethodDescription;
10    import net.bytebuddy.description.method.ParameterDescription;
11    import net.bytebuddy.description.method.ParameterList;
12    import net.bytebuddy.description.modifier.*;
13    import net.bytebuddy.description.type.TypeDefinition;
14    import net.bytebuddy.description.type.TypeDescription;
15    import net.bytebuddy.description.type.TypeList;
16    import net.bytebuddy.description.type.TypeVariableToken;
17    import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
18    import net.bytebuddy.dynamic.scaffold.*;
19    import net.bytebuddy.implementation.Implementation;
20    import net.bytebuddy.implementation.LoadedTypeInitializer;
21    import net.bytebuddy.implementation.attribute.*;
22    import net.bytebuddy.implementation.auxiliary.AuxiliaryType;
23    import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
24    import net.bytebuddy.matcher.ElementMatcher;
25    import net.bytebuddy.matcher.LatentMatcher;
26    import net.bytebuddy.pool.TypePool;
27    import net.bytebuddy.utility.CompoundList;
28   
29    import java.io.*;
30    import java.lang.annotation.Annotation;
31    import java.lang.reflect.*;
32    import java.util.*;
33    import java.util.jar.*;
34    import java.util.logging.Logger;
35   
36    import static net.bytebuddy.matcher.ElementMatchers.*;
37   
38    /**
39    * A dynamic type that is created at runtime, usually as the result of applying a
40    * {@link net.bytebuddy.dynamic.DynamicType.Builder} or as the result of an
41    * {@link net.bytebuddy.implementation.auxiliary.AuxiliaryType}.
42    * <p>&nbsp;</p>
43    * Note that the {@link TypeDescription}s will represent their
44    * unloaded forms and therefore differ from the loaded types, especially with regards to annotations.
45    */
 
46    public interface DynamicType {
47   
48    /**
49    * <p>
50    * Returns a description of this dynamic type.
51    * </p>
52    * <p>
53    * <b>Note</b>: This description will most likely differ from the binary representation of this type. Normally,
54    * annotations and intercepted methods are not added to this type description.
55    * </p>
56    *
57    * @return A description of this dynamic type.
58    */
59    TypeDescription getTypeDescription();
60   
61    /**
62    * Returns a byte array representing this dynamic type. This byte array might be reused by this dynamic type and
63    * must therefore not be altered.
64    *
65    * @return A byte array of the type's binary representation.
66    */
67    byte[] getBytes();
68   
69    /**
70    * <p>
71    * Returns a map of all auxiliary types that are required for making use of the main type.
72    * </p>
73    * <p>
74    * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
75    * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
76    * </p>
77    *
78    * @return A map of all auxiliary types by their descriptions to their binary representation.
79    */
80    Map<TypeDescription, byte[]> getAuxiliaryTypes();
81   
82    /**
83    * Returns all types that are implied by this dynamic type.
84    *
85    * @return A mapping from all type descriptions, the actual type and its auxiliary types to their binary
86    * representation
87    */
88    Map<TypeDescription, byte[]> getAllTypes();
89   
90    /**
91    * <p>
92    * Returns a map of all loaded type initializers for the main type and all auxiliary types, if any.
93    * </p>
94    * <p>
95    * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
96    * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
97    * </p>
98    *
99    * @return A mapping of all types' descriptions to their loaded type initializers.
100    */
101    Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers();
102   
103    /**
104    * Checks if a dynamic type requires some form of explicit type initialization, either for itself or for one
105    * of its auxiliary types, if any. This is the case when this dynamic type was defined to delegate method calls
106    * to a specific instance which is stored in a field of the created type. If this class serialized, it could not
107    * be used without its loaded type initializers since the field value represents a specific runtime context.
108    *
109    * @return {@code true} if this type requires explicit type initialization.
110    */
111    boolean hasAliveLoadedTypeInitializers();
112   
113    /**
114    * <p>
115    * Saves a dynamic type in a given folder using the Java class file format while respecting the naming conventions
116    * for saving compiled Java classes. All auxiliary types, if any, are saved in the same directory. The resulting
117    * folder structure will resemble the structure that is required for Java run times, i.e. each folder representing
118    * a segment of the package name. If the specified {@code folder} does not yet exist, it is created during the
119    * call of this method.
120    * </p>
121    * <p>
122    * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
123    * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
124    * </p>
125    *
126    * @param folder The base target folder for storing this dynamic type and its auxiliary types, if any.
127    * @return A map of type descriptions pointing to files with their stored binary representations within {@code folder}.
128    * @throws IOException Thrown if the underlying file operations cause an {@code IOException}.
129    */
130    Map<TypeDescription, File> saveIn(File folder) throws IOException;
131   
132    /**
133    * Injects the types of this dynamic type into a given <i>jar</i> file. Any pre-existent type with the same name
134    * is overridden during injection. The {@code target} file's folder must exist prior to calling this method. The
135    * file itself is overwritten or created depending on its prior existence.
136    *
137    * @param sourceJar The original jar file.
138    * @param targetJar The {@code source} jar file with the injected contents.
139    * @return The {@code target} jar file.
140    * @throws IOException If an IO exception occurs while injecting from the source into the target.
141    */
142    File inject(File sourceJar, File targetJar) throws IOException;
143   
144    /**
145    * Injects the types of this dynamic type into a given <i>jar</i> file. Any pre-existent type with the same name
146    * is overridden during injection.
147    *
148    * @param jar The jar file to replace with an injected version.
149    * @return The {@code jar} file.
150    * @throws IOException If an IO exception occurs while injecting into the jar.
151    */
152    File inject(File jar) throws IOException;
153   
154    /**
155    * Saves the contents of this dynamic type inside a <i>jar</i> file. The folder of the given {@code file} must
156    * exist prior to calling this method. The jar file is created with a simple manifest that only contains a version
157    * number.
158    *
159    * @param file The target file to which the <i>jar</i> is written to.
160    * @return The given {@code file}.
161    * @throws IOException If an IO exception occurs while writing the file.
162    */
163    File toJar(File file) throws IOException;
164   
165    /**
166    * Saves the contents of this dynamic type inside a <i>jar</i> file. The folder of the given {@code file} must
167    * exist prior to calling this method.
168    *
169    * @param file The target file to which the <i>jar</i> is written to.
170    * @param manifest The manifest of the created <i>jar</i>.
171    * @return The given {@code file}.
172    * @throws IOException If an IO exception occurs while writing the file.
173    */
174    File toJar(File file, Manifest manifest) throws IOException;
175   
176    /**
177    * A builder for creating a dynamic type.
178    *
179    * @param <T> A loaded type that the built type is guaranteed to be a subclass of.
180    */
 
181    interface Builder<T> {
182   
183    /**
184    * Applies the supplied {@link AsmVisitorWrapper} onto the {@link org.objectweb.asm.ClassVisitor} during building a dynamic type.
185    * Using an ASM visitor, it is possible to manipulate byte code directly. Byte Buddy does not validate directly created byte code
186    * and it remains the responsibility of the visitor's implementor to generate legal byte code. If several ASM visitor wrappers
187    * are registered, they are applied on top of another in their registration order.
188    *
189    * @param asmVisitorWrapper The ASM visitor wrapper to apply during
190    * @return A new builder that is equal to this builder and applies the ASM visitor wrapper.
191    */
192    Builder<T> visit(AsmVisitorWrapper asmVisitorWrapper);
193   
194    /**
195    * Names the dynamic type by the supplied name. The name needs to be fully qualified and in the binary format (packages separated
196    * by dots: {@code foo.Bar}). A type's package determines what other types are visible to the instrumented type and what methods
197    * can be overridden or be represented in method signatures or as field types.
198    *
199    * @param name The fully qualified name of the generated class in a binary format.
200    * @return A new builder that is equal to this builder but with the instrumented type named by the supplied name.
201    */
202    Builder<T> name(String name);
203   
204    /**
205    * Defines the supplied modifiers as the modifiers of the instrumented type.
206    *
207    * @param modifierContributor The modifiers of the instrumented type.
208    * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
209    */
210    Builder<T> modifiers(ModifierContributor.ForType... modifierContributor);
211   
212    /**
213    * Defines the supplied modifiers as the modifiers of the instrumented type.
214    *
215    * @param modifierContributors The modifiers of the instrumented type.
216    * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
217    */
218    Builder<T> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors);
219   
220    /**
221    * Defines the supplied modifiers as the modifiers of the instrumented type.
222    *
223    * @param modifiers The modifiers of the instrumented type.
224    * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
225    */
226    Builder<T> modifiers(int modifiers);
227   
228    /**
229    * Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
230    * type's new modifiers.
231    *
232    * @param modifierContributor The modifiers of the instrumented type.
233    * @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
234    */
235    Builder<T> merge(ModifierContributor.ForType... modifierContributor);
236   
237    /**
238    * Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
239    * type's new modifiers.
240    *
241    * @param modifierContributors The modifiers of the instrumented type.
242    * @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
243    */
244    Builder<T> merge(Collection<? extends ModifierContributor.ForType> modifierContributors);
245   
246    /**
247    * Applies the given type attribute appender onto the instrumented type. Using a type attribute appender, it is possible to append
248    * any type of meta data to a type, not only Java {@link Annotation}s.
249    *
250    * @param typeAttributeAppender The type attribute appender to apply.
251    * @return A new builder that is equal to this builder but with the supplied type attribute appender applied to the instrumented type.
252    */
253    Builder<T> attribute(TypeAttributeAppender typeAttributeAppender);
254   
255    /**
256    * Annotates the instrumented type with the supplied annotations.
257    *
258    * @param annotation The annotations to add to the instrumented type.
259    * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
260    */
261    Builder<T> annotateType(Annotation... annotation);
262   
263    /**
264    * Annotates the instrumented type with the supplied annotations.
265    *
266    * @param annotations The annotations to add to the instrumented type.
267    * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
268    */
269    Builder<T> annotateType(List<? extends Annotation> annotations);
270   
271    /**
272    * Annotates the instrumented type with the supplied annotations.
273    *
274    * @param annotation The annotations to add to the instrumented type.
275    * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
276    */
277    Builder<T> annotateType(AnnotationDescription... annotation);
278   
279    /**
280    * Annotates the instrumented type with the supplied annotations.
281    *
282    * @param annotations The annotations to add to the instrumented type.
283    * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
284    */
285    Builder<T> annotateType(Collection<? extends AnnotationDescription> annotations);
286   
287    /**
288    * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
289    * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
290    * are explicitly ignored.
291    *
292    * @param interfaceType The interface types to implement.
293    * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
294    */
295    MethodDefinition.ImplementationDefinition.Optional<T> implement(Type... interfaceType);
296   
297    /**
298    * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
299    * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
300    * are explicitly ignored.
301    *
302    * @param interfaceTypes The interface types to implement.
303    * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
304    */
305    MethodDefinition.ImplementationDefinition.Optional<T> implement(List<? extends Type> interfaceTypes);
306   
307    /**
308    * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
309    * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
310    * are explicitly ignored.
311    *
312    * @param interfaceType The interface types to implement.
313    * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
314    */
315    MethodDefinition.ImplementationDefinition.Optional<T> implement(TypeDefinition... interfaceType);
316   
317    /**
318    * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
319    * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
320    * are explicitly ignored.
321    *
322    * @param interfaceTypes The interface types to implement.
323    * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
324    */
325    MethodDefinition.ImplementationDefinition.Optional<T> implement(Collection<? extends TypeDefinition> interfaceTypes);
326   
327    /**
328    * <p>
329    * Executes the supplied byte code appender within the beginning of the instrumented type's type initializer. The
330    * supplied byte code appender <b>must not return</b> from the method. If several byte code appenders are supplied,
331    * they are executed within their application order.
332    * </p>
333    * <p>
334    * This method should only be used for preparing an instrumented type with a specific configuration. Normally,
335    * a byte code appender is applied via Byte Buddy's standard API by invoking {@link Builder#invokable(ElementMatcher)}
336    * using the {@link net.bytebuddy.matcher.ElementMatchers#isTypeInitializer()} matcher.
337    * </p>
338    *
339    * @param byteCodeAppender The byte code appender to execute within the instrumented type's type initializer.
340    * @return A new builder that is equal to this builder but with the supplied byte code appender being executed within
341    * the instrumented type's type initializer.
342    */
343    Builder<T> initializer(ByteCodeAppender byteCodeAppender);
344   
345    /**
346    * Executes the supplied loaded type initializer when loading the created instrumented type. If several loaded
347    * type initializers are supplied, each loaded type initializer is executed in its registration order.
348    *
349    * @param loadedTypeInitializer The loaded type initializer to execute upon loading the instrumented type.
350    * @return A new builder that is equal to this builder but with the supplied loaded type initializer executed upon
351    * loading the instrumented type.
352    */
353    Builder<T> initializer(LoadedTypeInitializer loadedTypeInitializer);
354   
355    /**
356    * Defines the supplied type variable without any bounds as a type variable of the instrumented type.
357    *
358    * @param symbol The type variable's symbol.
359    * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
360    */
361    TypeVariableDefinition<T> typeVariable(String symbol);
362   
363    /**
364    * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
365    *
366    * @param symbol The type variable's symbol.
367    * @param bound The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
368    * should be equal to the currently instrumented type.
369    * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
370    */
371    TypeVariableDefinition<T> typeVariable(String symbol, Type... bound);
372   
373    /**
374    * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
375    *
376    * @param symbol The type variable's symbol.
377    * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
378    * should be equal to the currently instrumented type.
379    * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
380    */
381    TypeVariableDefinition<T> typeVariable(String symbol, List<? extends Type> bounds);
382   
383    /**
384    * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
385    *
386    * @param symbol The type variable's symbol.
387    * @param bound The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
388    * should be equal to the currently instrumented type.
389    * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
390    */
391    TypeVariableDefinition<T> typeVariable(String symbol, TypeDefinition... bound);
392   
393    /**
394    * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
395    *
396    * @param symbol The type variable's symbol.
397    * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
398    * should be equal to the currently instrumented type.
399    * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
400    */
401    TypeVariableDefinition<T> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
402   
403    /**
404    * Defines the specified field as a field of the built dynamic type.
405    *
406    * @param name The name of the field.
407    * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
408    * should be equal to the currently instrumented type.
409    * @param modifierContributor The modifiers of the field.
410    * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
411    * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
412    */
413    FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor);
414   
415    /**
416    * Defines the specified field as a field of the built dynamic type.
417    *
418    * @param name The name of the field.
419    * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
420    * should be equal to the currently instrumented type.
421    * @param modifierContributors The modifiers of the field.
422    * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
423    * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
424    */
425    FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors);
426   
427    /**
428    * Defines the specified field as a field of the built dynamic type.
429    *
430    * @param name The name of the field.
431    * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
432    * should be equal to the currently instrumented type.
433    * @param modifiers The modifiers of the field.
434    * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
435    * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
436    */
437    FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, int modifiers);
438   
439    /**
440    * Defines the specified field as a field of the built dynamic type.
441    *
442    * @param name The name of the field.
443    * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
444    * should be equal to the currently instrumented type.
445    * @param modifierContributor The modifiers of the field.
446    * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
447    * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
448    */
449    FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor);
450   
451    /**
452    * Defines the specified field as a field of the built dynamic type.
453    *
454    * @param name The name of the field.
455    * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
456    * should be equal to the currently instrumented type.
457    * @param modifierContributors The modifiers of the field.
458    * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
459    * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
460    */
461    FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors);
462   
463    /**
464    * Defines the specified field as a field of the built dynamic type.
465    *
466    * @param name The name of the field.
467    * @param type The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
468    * should be equal to the currently instrumented type.
469    * @param modifiers The modifiers of the field.
470    * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
471    * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
472    */
473    FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, int modifiers);
474   
475    /**
476    * Defines a field that is similar to the supplied field but without copying any annotations on the field.
477    *
478    * @param field The field to imitate as a field of the instrumented type.
479    * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
480    * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
481    */
482    FieldDefinition.Optional.Valuable<T> define(Field field);
483   
484    /**
485    * Defines a field that is similar to the supplied field but without copying any annotations on the field.
486    *
487    * @param field The field to imitate as a field of the instrumented type.
488    * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
489    * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
490    */
491    FieldDefinition.Optional.Valuable<T> define(FieldDescription field);
492   
493    /**
494    * Defines a private, static, final field for a serial version UID of the given value.
495    *
496    * @param serialVersionUid The serial version UID to define as a value.
497    * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
498    * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
499    */
500    FieldDefinition.Optional<T> serialVersionUid(long serialVersionUid);
501   
502    /**
503    * <p>
504    * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
505    * default value, annotations or custom attributes.
506    * </p>
507    * <p>
508    * When a type is redefined or rebased, any annotations that the field declared previously is preserved
509    * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
510    * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
511    * altered, annotation retention must be disabled.
512    * </p>
513    * <p>
514    * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
515    * over the previous definition, i.e. the previous field definition is no longer applied.
516    * </p>
517    *
518    * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
519    * @return A builder that allows for changing a field's definition.
520    */
521    FieldDefinition.Valuable<T> field(ElementMatcher<? super FieldDescription> matcher);
522   
523    /**
524    * <p>
525    * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
526    * default value, annotations or custom attributes. Using a latent matcher gives opportunity to resolve an
527    * {@link ElementMatcher} based on the instrumented type before applying the matcher.
528    * </p>
529    * <p>
530    * When a type is redefined or rebased, any annotations that the field declared previously is preserved
531    * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
532    * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
533    * altered, annotation retention must be disabled.
534    * </p>
535    * <p>
536    * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
537    * over the previous definition, i.e. the previous field definition is no longer applied.
538    * </p>
539    *
540    * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
541    * @return A builder that allows for changing a field's definition.
542    */
543    FieldDefinition.Valuable<T> field(LatentMatcher<? super FieldDescription> matcher);
544   
545    /**
546    * <p>
547    * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
548    * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
549    * </p>
550    * <p>
551    * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
552    * is to be ignored, this matcher is no longer executed.
553    * </p>
554    *
555    * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
556    * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
557    * instrumentation.
558    */
559    Builder<T> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods);
560   
561    /**
562    * <p>
563    * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
564    * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
565    * Using a latent matcher gives opportunity to resolve an {@link ElementMatcher} based on the instrumented type before applying the
566    * matcher.
567    * </p>
568    * <p>
569    * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
570    * is to be ignored, this matcher is no longer executed.
571    * </p>
572    *
573    * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
574    * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
575    * instrumentation.
576    */
577    Builder<T> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods);
578   
579    /**
580    * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
581    * type variables can be defined in subsequent steps.
582    *
583    * @param name The name of the method.
584    * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
585    * should be equal to the currently instrumented type.
586    * @param modifierContributor The method's modifiers.
587    * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
588    */
589    MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor);
590   
591    /**
592    * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
593    * type variables can be defined in subsequent steps.
594    *
595    * @param name The name of the method.
596    * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
597    * should be equal to the currently instrumented type.
598    * @param modifierContributors The method's modifiers.
599    * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
600    */
601    MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
602   
603    /**
604    * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
605    * type variables can be defined in subsequent steps.
606    *
607    * @param name The name of the method.
608    * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
609    * should be equal to the currently instrumented type.
610    * @param modifiers The method's modifiers.
611    * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
612    */
613    MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, int modifiers);
614   
615    /**
616    * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
617    * type variables can be defined in subsequent steps.
618    *
619    * @param name The name of the method.
620    * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
621    * should be equal to the currently instrumented type.
622    * @param modifierContributor The method's modifiers.
623    * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
624    */
625    MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor);
626   
627    /**
628    * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
629    * type variables can be defined in subsequent steps.
630    *
631    * @param name The name of the method.
632    * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
633    * should be equal to the currently instrumented type.
634    * @param modifierContributors The method's modifiers.
635    * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
636    */
637    MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
638   
639    /**
640    * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
641    * type variables can be defined in subsequent steps.
642    *
643    * @param name The name of the method.
644    * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
645    * should be equal to the currently instrumented type.
646    * @param modifiers The method's modifiers.
647    * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
648    */
649    MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, int modifiers);
650   
651    /**
652    * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
653    * type variables can be defined in subsequent steps.
654    *
655    * @param modifierContributor The constructor's modifiers.
656    * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
657    */
658    MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(ModifierContributor.ForMethod... modifierContributor);
659   
660    /**
661    * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
662    * type variables can be defined in subsequent steps.
663    *
664    * @param modifierContributors The constructor's modifiers.
665    * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
666    */
667    MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors);
668   
669    /**
670    * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
671    * type variables can be defined in subsequent steps.
672    *
673    * @param modifiers The constructor's modifiers.
674    * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
675    */
676    MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(int modifiers);
677   
678    /**
679    * Defines a method that is similar to the supplied method but without copying any annotations of the method or method parameters.
680    *
681    * @param method The method to imitate as a method of the instrumented type.
682    * @return A builder that allows for defining an implementation for the method.
683    */
684    MethodDefinition.ImplementationDefinition<T> define(Method method);
685   
686    /**
687    * Defines a constructor that is similar to the supplied constructor but without copying any annotations of the constructor or
688    * constructor parameters.
689    *
690    * @param constructor The constructor to imitate as a method of the instrumented type.
691    * @return A builder that allows for defining an implementation for the constructor.
692    */
693    MethodDefinition.ImplementationDefinition<T> define(Constructor<?> constructor);
694   
695    /**
696    * Defines a method or constructor that is similar to the supplied method description but without copying any annotations of
697    * the method/constructor or method/constructor parameters.
698    *
699    * @param methodDescription The method description to imitate as a method or constructor of the instrumented type.
700    * @return A builder that allows for defining an implementation for the method or constructor.
701    */
702    MethodDefinition.ImplementationDefinition<T> define(MethodDescription methodDescription);
703   
704    /**
705    * <p>
706    * Matches a method that is already declared or inherited by the instrumented type. This gives opportunity to change or to
707    * override that method's implementation, default value, annotations or custom attributes. It is also possible to make
708    * a method abstract.
709    * </p>
710    * <p>
711    * When a type is redefined or rebased, any annotations that the method declared previously is preserved
712    * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
713    * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
714    * altered, annotation retention must be disabled.
715    * </p>
716    * <p>
717    * If a method is already matched by a previously specified matcher, the new method definition gets precedence
718    * over the previous definition, i.e. the previous method definition is no longer applied.
719    * </p>
720    * <p>
721    * Note that the specified definition does never apply for methods that are explicitly ignored.
722    * </p>
723    *
724    * @param matcher The matcher that determines what methods are affected by the subsequent specification.
725    * @return A builder that allows for changing a method's or constructor's definition.
726    */
727    MethodDefinition.ImplementationDefinition<T> method(ElementMatcher<? super MethodDescription> matcher);
728   
729    /**
730    * <p>
731    * Matches a constructor that is already declared by the instrumented type. This gives opportunity to change that constructor's
732    * implementation, default value, annotations or custom attributes.
733    * </p>
734    * <p>
735    * When a type is redefined or rebased, any annotations that the constructor declared previously is preserved
736    * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
737    * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
738    * altered, annotation retention must be disabled.
739    * </p>
740    * <p>
741    * If a constructor is already matched by a previously specified matcher, the new constructor definition gets precedence
742    * over the previous definition, i.e. the previous constructor definition is no longer applied.
743    * </p>
744    * <p>
745    * Note that the specified definition does never apply for methods that are explicitly ignored.
746    * </p>
747    *
748    * @param matcher The matcher that determines what constructors are affected by the subsequent specification.
749    * @return A builder that allows for changing a method's or constructor's definition.
750    */
751    MethodDefinition.ImplementationDefinition<T> constructor(ElementMatcher<? super MethodDescription> matcher);
752   
753    /**
754    * <p>
755    * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
756    * opportunity to change or to override that method's or constructor's implementation, default value, annotations
757    * or custom attributes. It is also possible to make a method abstract.
758    * </p>
759    * <p>
760    * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
761    * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
762    * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
763    * altered, annotation retention must be disabled.
764    * </p>
765    * <p>
766    * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
767    * over the previous definition, i.e. the previous definition is no longer applied.
768    * </p>
769    * <p>
770    * Note that the specified definition does never apply for methods that are explicitly ignored.
771    * </p>
772    *
773    * @param matcher The matcher that determines what methods or constructors are affected by the subsequent specification.
774    * @return A builder that allows for changing a method's or constructor's definition.
775    */
776    MethodDefinition.ImplementationDefinition<T> invokable(ElementMatcher<? super MethodDescription> matcher);
777   
778    /**
779    * <p>
780    * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
781    * opportunity to change or to override that method's or constructor's implementation, default value, annotations
782    * or custom attributes. It is also possible to make a method abstract. Using a latent matcher gives opportunity
783    * to resolve an {@link ElementMatcher} based on the instrumented type before applying the matcher.
784    * </p>
785    * <p>
786    * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
787    * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
788    * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
789    * altered, annotation retention must be disabled.
790    * </p>
791    * <p>
792    * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
793    * over the previous definition, i.e. the previous definition is no longer applied.
794    * </p>
795    * <p>
796    * Note that the specified definition does never apply for methods that are explicitly ignored.
797    * </p>
798    *
799    * @param matcher The matcher that determines what declared methods or constructors are affected by the subsequent specification.
800    * @return A builder that allows for changing a method's or constructor's definition.
801    */
802    MethodDefinition.ImplementationDefinition<T> invokable(LatentMatcher<? super MethodDescription> matcher);
803   
804    /**
805    * <p>
806    * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
807    * </p>
808    * <p>
809    * Other than {@link DynamicType.Builder#make(TypePool)}, this method supplies a context-dependant type pool to the underlying class writer.
810    * Supplying a type pool only makes sense if custom byte code is created by adding a custom {@link AsmVisitorWrapper} where ASM might be
811    * required to compute stack map frames by processing information over any mentioned type's class hierarchy.
812    * </p>
813    *
814    * @return An unloaded dynamic type representing the type specified by this builder.
815    */
816    DynamicType.Unloaded<T> make();
817   
818    /**
819    * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
820    *
821    * @param typePool A type pool that is used for computing stack map frames by the underlying class writer, if required.
822    * @return An unloaded dynamic type representing the type specified by this builder.
823    */
824    DynamicType.Unloaded<T> make(TypePool typePool);
825   
826    /**
827    * A builder for a type variable definition.
828    *
829    * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
830    */
 
831    interface TypeVariableDefinition<S> extends Builder<S> {
832   
833    /**
834    * Annotates the previously defined type variable with the supplied annotations.
835    *
836    * @param annotation The annotations to declare on the previously defined type variable.
837    * @return A new builder that is equal to this builder but with the given annotations declared
838    * on the previously defined type variable.
839    */
840    TypeVariableDefinition<S> annotateTypeVariable(Annotation... annotation);
841   
842    /**
843    * Annotates the previously defined type variable with the supplied annotations.
844    *
845    * @param annotations The annotations to declare on the previously defined type variable.
846    * @return A new builder that is equal to this builder but with the given annotations declared
847    * on the previously defined type variable.
848    */
849    TypeVariableDefinition<S> annotateTypeVariable(List<? extends Annotation> annotations);
850   
851    /**
852    * Annotates the previously defined type variable with the supplied annotations.
853    *
854    * @param annotation The annotations to declare on the previously defined type variable.
855    * @return A new builder that is equal to this builder but with the given annotations declared
856    * on the previously defined type variable.
857    */
858    TypeVariableDefinition<S> annotateTypeVariable(AnnotationDescription... annotation);
859   
860    /**
861    * Annotates the previously defined type variable with the supplied annotations.
862    *
863    * @param annotations The annotations to declare on the previously defined type variable.
864    * @return A new builder that is equal to this builder but with the given annotations declared
865    * on the previously defined type variable.
866    */
867    TypeVariableDefinition<S> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
868   
869    /**
870    * An abstract base implementation of a type variable definition.
871    *
872    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
873    */
 
874    abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements TypeVariableDefinition<U> {
875   
 
876  0 toggle @Override
877    public TypeVariableDefinition<U> annotateTypeVariable(Annotation... annotation) {
878  0 return annotateTypeVariable(Arrays.asList(annotation));
879    }
880   
 
881  0 toggle @Override
882    public TypeVariableDefinition<U> annotateTypeVariable(List<? extends Annotation> annotations) {
883  0 return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
884    }
885   
 
886  14 toggle @Override
887    public TypeVariableDefinition<U> annotateTypeVariable(AnnotationDescription... annotation) {
888  14 return annotateTypeVariable(Arrays.asList(annotation));
889    }
890    }
891    }
892   
893    /**
894    * A builder for a field definition.
895    *
896    * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
897    */
 
898    interface FieldDefinition<S> {
899   
900    /**
901    * Annotates the previously defined or matched field with the supplied annotations.
902    *
903    * @param annotation The annotations to declare on the previously defined or matched field.
904    * @return A new builder that is equal to this builder but with the given annotations declared
905    * on the previously defined or matched field.
906    */
907    FieldDefinition.Optional<S> annotateField(Annotation... annotation);
908   
909    /**
910    * Annotates the previously defined or matched field with the supplied annotations.
911    *
912    * @param annotations The annotations to declare on the previously defined or matched field.
913    * @return A new builder that is equal to this builder but with the given annotations declared
914    * on the previously defined or matched field.
915    */
916    FieldDefinition.Optional<S> annotateField(List<? extends Annotation> annotations);
917   
918    /**
919    * Annotates the previously defined or matched field with the supplied annotations.
920    *
921    * @param annotation The annotations to declare on the previously defined or matched field.
922    * @return A new builder that is equal to this builder but with the given annotations declared
923    * on the previously defined or matched field.
924    */
925    FieldDefinition.Optional<S> annotateField(AnnotationDescription... annotation);
926   
927    /**
928    * Annotates the previously defined or matched field with the supplied annotations.
929    *
930    * @param annotations The annotations to declare on the previously defined or matched field.
931    * @return A new builder that is equal to this builder but with the given annotations declared
932    * on the previously defined or matched field.
933    */
934    FieldDefinition.Optional<S> annotateField(Collection<? extends AnnotationDescription> annotations);
935   
936    /**
937    * Applies the supplied attribute appender factory onto the previously defined or matched field.
938    *
939    * @param fieldAttributeAppenderFactory The field attribute appender factory that should be applied on the
940    * previously defined or matched field.
941    * @return A new builder that is equal to this builder but with the supplied field attribute appender factory
942    * applied to the previously defined or matched field.
943    */
944    FieldDefinition.Optional<S> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory);
945   
946    /**
947    * Applies the supplied field transformer onto the previously defined or matched field. The transformed
948    * field is written <i>as it is</i> and it not subject to any validations.
949    *
950    * @param fieldTransformer The field transformer to apply to the previously defined or matched field.
951    * @return A new builder that is equal to this builder but with the supplied field transformer
952    * applied to the previously defined or matched field.
953    */
954    FieldDefinition.Optional<S> transform(FieldTransformer fieldTransformer);
955   
956    /**
957    * A builder for a field definition that allows for defining a value.
958    *
959    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
960    */
 
961    interface Valuable<U> extends FieldDefinition<U> {
962   
963    /**
964    * <p>
965    * Defines the supplied {@code boolean} value as a default value of the previously defined or matched field. The value can only
966    * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int}. For non-boolean
967    * fields, the field's value is set to {@code 0} for {@code false} or {@code 1} for {@code true}.
968    * </p>
969    * <p>
970    * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
971    * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
972    * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
973    * </p>
974    *
975    * @param value The value to define as a default value of the defined field.
976    * @return A new builder that is equal to this builder but with the given default value declared for the
977    * previously defined or matched field.
978    */
979    FieldDefinition.Optional<U> value(boolean value);
980   
981    /**
982    * <p>
983    * Defines the supplied {@code int} value as a default value of the previously defined or matched field. The value can only
984    * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int} where the
985    * value must be within the numeric type's range. The {@code boolean} type is regarded as a numeric type with the possible
986    * values of {@code 0} and {@code 1} representing {@code false} and {@code true}.
987    * </p>
988    * <p>
989    * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
990    * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
991    * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
992    * </p>
993    *
994    * @param value The value to define as a default value of the defined field.
995    * @return A new builder that is equal to this builder but with the given default value declared for the
996    * previously defined or matched field.
997    */
998    FieldDefinition.Optional<U> value(int value);
999   
1000    /**
1001    * <p>
1002    * Defines the supplied {@code long} value as a default value of the previously defined or matched field.
1003    * </p>
1004    * <p>
1005    * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1006    * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1007    * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1008    * </p>
1009    *
1010    * @param value The value to define as a default value of the defined field.
1011    * @return A new builder that is equal to this builder but with the given default value declared for the
1012    * previously defined or matched field.
1013    */
1014    FieldDefinition.Optional<U> value(long value);
1015   
1016    /**
1017    * <p>
1018    * Defines the supplied {@code float} value as a default value of the previously defined or matched field.
1019    * </p>
1020    * <p>
1021    * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1022    * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1023    * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1024    * </p>
1025    *
1026    * @param value The value to define as a default value of the defined field.
1027    * @return A new builder that is equal to this builder but with the given default value declared for the
1028    * previously defined or matched field.
1029    */
1030    FieldDefinition.Optional<U> value(float value);
1031   
1032    /**
1033    * <p>
1034    * Defines the supplied {@code double} value as a default value of the previously defined or matched field.
1035    * </p>
1036    * <p>
1037    * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1038    * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1039    * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1040    * </p>
1041    *
1042    * @param value The value to define as a default value of the defined field.
1043    * @return A new builder that is equal to this builder but with the given default value declared for the
1044    * previously defined or matched field.
1045    */
1046    FieldDefinition.Optional<U> value(double value);
1047   
1048    /**
1049    * <p>
1050    * Defines the supplied {@link String} value as a default value of the previously defined or matched field.
1051    * </p>
1052    * <p>
1053    * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1054    * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1055    * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1056    * </p>
1057    *
1058    * @param value The value to define as a default value of the defined field.
1059    * @return A new builder that is equal to this builder but with the given default value declared for the
1060    * previously defined or matched field.
1061    */
1062    FieldDefinition.Optional<U> value(String value);
1063    }
1064   
1065    /**
1066    * A builder for an optional field definition.
1067    *
1068    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1069    */
 
1070    interface Optional<U> extends FieldDefinition<U>, Builder<U> {
1071   
1072    /**
1073    * A builder for an optional field definition that allows for defining a value.
1074    *
1075    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1076    */
 
1077    interface Valuable<V> extends FieldDefinition.Valuable<V>, Optional<V> {
1078   
1079    /**
1080    * An abstract base implementation of an optional field definition that allows for defining a value.
1081    *
1082    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1083    */
 
1084    abstract class AbstractBase<U> extends Optional.AbstractBase<U> implements Optional.Valuable<U> {
1085   
 
1086  3 toggle @Override
1087    public FieldDefinition.Optional<U> value(boolean value) {
1088  3 return defaultValue(value ? 1 : 0);
1089    }
1090   
 
1091  14 toggle @Override
1092    public FieldDefinition.Optional<U> value(int value) {
1093  14 return defaultValue(value);
1094    }
1095   
 
1096  9 toggle @Override
1097    public FieldDefinition.Optional<U> value(long value) {
1098  9 return defaultValue(value);
1099    }
1100   
 
1101  3 toggle @Override
1102    public FieldDefinition.Optional<U> value(float value) {
1103  3 return defaultValue(value);
1104    }
1105   
 
1106  3 toggle @Override
1107    public FieldDefinition.Optional<U> value(double value) {
1108  3 return defaultValue(value);
1109    }
1110   
 
1111  8 toggle @Override
1112    public FieldDefinition.Optional<U> value(String value) {
1113  8 if (value == null) {
1114  1 throw new IllegalArgumentException("Cannot set null as a default value");
1115    }
1116  7 return defaultValue(value);
1117    }
1118   
1119    /**
1120    * Defines the supplied value as a default value of the previously defined or matched field.
1121    *
1122    * @param defaultValue The value to define as a default value of the defined field.
1123    * @return A new builder that is equal to this builder but with the given default value declared for the
1124    * previously defined or matched field.
1125    */
1126    protected abstract FieldDefinition.Optional<U> defaultValue(Object defaultValue);
1127   
1128    /**
1129    * An adapter for an optional field definition that allows for defining a value.
1130    *
1131    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1132    */
 
1133    protected abstract static class Adapter<V> extends Optional.Valuable.AbstractBase<V> {
1134   
1135    /**
1136    * The field attribute appender factory to apply.
1137    */
1138    protected final FieldAttributeAppender.Factory fieldAttributeAppenderFactory;
1139   
1140    /**
1141    * The field transformer to apply.
1142    */
1143    protected final FieldTransformer fieldTransformer;
1144   
1145    /**
1146    * The field's default value or {@code null} if no value is to be defined.
1147    */
1148    protected final Object defaultValue;
1149   
1150    /**
1151    * Creates a new field adapter.
1152    *
1153    * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
1154    * @param fieldTransformer The field transformer to apply.
1155    * @param defaultValue The field's default value or {@code null} if no value is to be defined.
1156    */
 
1157  654 toggle protected Adapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory, FieldTransformer fieldTransformer, Object defaultValue) {
1158  654 this.fieldAttributeAppenderFactory = fieldAttributeAppenderFactory;
1159  654 this.fieldTransformer = fieldTransformer;
1160  654 this.defaultValue = defaultValue;
1161    }
1162   
 
1163  4 toggle @Override
1164    public FieldDefinition.Optional<V> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory) {
1165  4 return materialize(new FieldAttributeAppender.Factory.Compound(this.fieldAttributeAppenderFactory, fieldAttributeAppenderFactory), fieldTransformer, defaultValue);
1166    }
1167   
 
1168  5 toggle @Override
1169    public FieldDefinition.Optional<V> transform(FieldTransformer fieldTransformer) {
1170  5 return materialize(fieldAttributeAppenderFactory, new FieldTransformer.Compound(this.fieldTransformer, fieldTransformer), defaultValue);
1171    }
1172   
 
1173  39 toggle @Override
1174    protected FieldDefinition.Optional<V> defaultValue(Object defaultValue) {
1175  39 return materialize(fieldAttributeAppenderFactory, fieldTransformer, defaultValue);
1176    }
1177   
1178    /**
1179    * Creates a new optional field definition for which all of the supplied values are represented.
1180    *
1181    * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
1182    * @param fieldTransformer The field transformer to apply.
1183    * @param defaultValue The field's default value or {@code null} if no value is to be defined.
1184    * @return A new field definition that represents the supplied values.
1185    */
1186    protected abstract FieldDefinition.Optional<V> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory, FieldTransformer fieldTransformer, Object defaultValue);
1187   
 
1188  18 toggle @Override
1189    public boolean equals(Object other) {
1190  18 if (this == other) return true;
1191  18 if (other == null || getClass() != other.getClass()) return false;
1192  18 Adapter<?> adapter = (Adapter<?>) other;
1193  18 return fieldAttributeAppenderFactory.equals(adapter.fieldAttributeAppenderFactory)
1194    && fieldTransformer.equals(adapter.fieldTransformer)
1195  14 && (defaultValue != null ? defaultValue.equals(adapter.defaultValue) : adapter.defaultValue == null);
1196    }
1197   
 
1198  22 toggle @Override
1199    public int hashCode() {
1200  22 int result = fieldAttributeAppenderFactory.hashCode();
1201  22 result = 31 * result + fieldTransformer.hashCode();
1202  22 result = 31 * result + (defaultValue != null ? defaultValue.hashCode() : 0);
1203  22 return result;
1204    }
1205    }
1206    }
1207    }
1208   
1209    /**
1210    * An abstract base implementation for an optional field definition.
1211    *
1212    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1213    */
 
1214    abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements FieldDefinition.Optional<U> {
1215   
 
1216  5 toggle @Override
1217    public FieldDefinition.Optional<U> annotateField(Annotation... annotation) {
1218  5 return annotateField(Arrays.asList(annotation));
1219    }
1220   
 
1221  5 toggle @Override
1222    public FieldDefinition.Optional<U> annotateField(List<? extends Annotation> annotations) {
1223  5 return annotateField(new AnnotationList.ForLoadedAnnotations(annotations));
1224    }
1225   
 
1226  1 toggle @Override
1227    public FieldDefinition.Optional<U> annotateField(AnnotationDescription... annotation) {
1228  1 return annotateField(Arrays.asList(annotation));
1229    }
1230    }
1231    }
1232    }
1233   
1234    /**
1235    * A builder for a method definition.
1236    *
1237    * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1238    */
 
1239    interface MethodDefinition<S> extends Builder<S> {
1240   
1241    /**
1242    * Annotates the previously defined or matched method with the supplied annotations.
1243    *
1244    * @param annotation The annotations to declare on the previously defined or matched method.
1245    * @return A new builder that is equal to this builder but with the given annotations declared
1246    * on the previously defined or matched method.
1247    */
1248    MethodDefinition<S> annotateMethod(Annotation... annotation);
1249   
1250    /**
1251    * Annotates the previously defined or matched method with the supplied annotations.
1252    *
1253    * @param annotations The annotations to declare on the previously defined or matched method.
1254    * @return A new builder that is equal to this builder but with the given annotations declared
1255    * on the previously defined or matched method.
1256    */
1257    MethodDefinition<S> annotateMethod(List<? extends Annotation> annotations);
1258   
1259    /**
1260    * Annotates the previously defined or matched method with the supplied annotations.
1261    *
1262    * @param annotation The annotations to declare on the previously defined or matched method.
1263    * @return A new builder that is equal to this builder but with the given annotations declared
1264    * on the previously defined or matched method.
1265    */
1266    MethodDefinition<S> annotateMethod(AnnotationDescription... annotation);
1267   
1268    /**
1269    * Annotates the previously defined or matched method with the supplied annotations.
1270    *
1271    * @param annotations The annotations to declare on the previously defined or matched method.
1272    * @return A new builder that is equal to this builder but with the given annotations declared
1273    * on the previously defined or matched method.
1274    */
1275    MethodDefinition<S> annotateMethod(Collection<? extends AnnotationDescription> annotations);
1276   
1277    /**
1278    * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1279    *
1280    * @param index The parameter's index.
1281    * @param annotation The annotations to declare on the previously defined or matched method.
1282    * @return A new builder that is equal to this builder but with the given annotations declared
1283    * on the previously defined or matched method's parameter of the given index.
1284    */
1285    MethodDefinition<S> annotateParameter(int index, Annotation... annotation);
1286   
1287    /**
1288    * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1289    *
1290    * @param index The parameter's index.
1291    * @param annotations The annotations to declare on the previously defined or matched method.
1292    * @return A new builder that is equal to this builder but with the given annotations declared
1293    * on the previously defined or matched method's parameter of the given index.
1294    */
1295    MethodDefinition<S> annotateParameter(int index, List<? extends Annotation> annotations);
1296   
1297    /**
1298    * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1299    *
1300    * @param index The parameter's index.
1301    * @param annotation The annotations to declare on the previously defined or matched method.
1302    * @return A new builder that is equal to this builder but with the given annotations declared
1303    * on the previously defined or matched method's parameter of the given index.
1304    */
1305    MethodDefinition<S> annotateParameter(int index, AnnotationDescription... annotation);
1306   
1307    /**
1308    * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1309    *
1310    * @param index The parameter's index.
1311    * @param annotations The annotations to declare on the previously defined or matched method.
1312    * @return A new builder that is equal to this builder but with the given annotations declared
1313    * on the previously defined or matched method's parameter of the given index.
1314    */
1315    MethodDefinition<S> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations);
1316   
1317    /**
1318    * Applies the supplied method attribute appender factory onto the previously defined or matched method.
1319    *
1320    * @param methodAttributeAppenderFactory The method attribute appender factory that should be applied on the
1321    * previously defined or matched method.
1322    * @return A new builder that is equal to this builder but with the supplied method attribute appender factory
1323    * applied to the previously defined or matched method.
1324    */
1325    MethodDefinition<S> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory);
1326   
1327    /**
1328    * Applies the supplied method transformer onto the previously defined or matched method. The transformed
1329    * method is written <i>as it is</i> and it not subject to any validations.
1330    *
1331    * @param methodTransformer The method transformer to apply to the previously defined or matched method.
1332    * @return A new builder that is equal to this builder but with the supplied method transformer
1333    * applied to the previously defined or matched method.
1334    */
1335    MethodDefinition<S> transform(MethodTransformer methodTransformer);
1336   
1337    /**
1338    * A builder for a method definition with a receiver type.
1339    *
1340    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1341    */
 
1342    interface ReceiverTypeDefinition<U> extends MethodDefinition<U> {
1343   
1344    /**
1345    * Defines the supplied (annotated) receiver type for the previously defined or matched method.
1346    *
1347    * @param receiverType The receiver type to define on the previously defined or matched method.
1348    * @return A new builder that is equal to this builder but with the given type defined as the
1349    * receiver on the previously defined or matched method.
1350    */
1351    MethodDefinition<U> receiverType(AnnotatedElement receiverType);
1352   
1353    /**
1354    * Defines the supplied (annotated) receiver type for the previously defined or matched method.
1355    *
1356    * @param receiverType The receiver type to define on the previously defined or matched method.
1357    * @return A new builder that is equal to this builder but with the given type defined as the
1358    * receiver on the previously defined or matched method.
1359    */
1360    MethodDefinition<U> receiverType(TypeDescription.Generic receiverType);
1361   
1362    /**
1363    * An abstract base implementation of a method definition that can accept a receiver type.
1364    *
1365    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1366    */
 
1367    abstract class AbstractBase<V> extends MethodDefinition.AbstractBase<V> implements ReceiverTypeDefinition<V> {
1368   
 
1369  0 toggle @Override
1370    public MethodDefinition<V> receiverType(AnnotatedElement receiverType) {
1371  0 return receiverType(TypeDescription.Generic.AnnotationReader.DISPATCHER.resolve(receiverType));
1372    }
1373    }
1374    }
1375   
1376    /**
1377    * A builder for defining an implementation of a method.
1378    *
1379    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1380    */
 
1381    interface ImplementationDefinition<U> {
1382   
1383    /**
1384    * Implements the previously defined or matched method by the supplied implementation. A method interception
1385    * is typically implemented in one of the following ways:
1386    * <ol>
1387    * <li>If a method is declared by the instrumented type and the type builder creates a subclass or redefinition,
1388    * any preexisting method is replaced by the given implementation. Any previously defined implementation is lost.</li>
1389    * <li>If a method is declared by the instrumented type and the type builder creates a rebased version of the
1390    * instrumented type, the original method is preserved within a private, synthetic method within the instrumented
1391    * type. The original method therefore remains invokeable and is treated as the direct super method of the new
1392    * method. When rebasing a type, it therefore becomes possible to invoke a non-virtual method's super method
1393    * when a preexisting method body is replaced.</li>
1394    * <li>If a virtual method is inherited from a super type, it is overridden. The overridden method is available
1395    * for super method invocation.</li>
1396    * </ol>
1397    *
1398    * @param implementation The implementation for implementing the previously defined or matched method.
1399    * @return A new builder where the previously defined or matched method is implemented by the
1400    * supplied implementation.
1401    */
1402    MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation);
1403   
1404    /**
1405    * Defines the previously defined or matched method to be {@code abstract}.
1406    *
1407    * @return A new builder where the previously defined or matched method is implemented to be abstract.
1408    */
1409    MethodDefinition.ReceiverTypeDefinition<U> withoutCode();
1410   
1411    /**
1412    * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
1413    * value must be supplied in its unloaded state, i.e. enumerations as {@link net.bytebuddy.description.enumeration.EnumerationDescription},
1414    * types as {@link TypeDescription} and annotations as {@link AnnotationDescription}. For supplying loaded types, use
1415    * {@link ImplementationDefinition#defaultValue(Object, Class)} must be used.
1416    *
1417    * @param value The value to be defined as a default value.
1418    * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
1419    */
1420    MethodDefinition.ReceiverTypeDefinition<U> defaultValue(Object value);
1421   
1422    /**
1423    * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
1424    * value must be supplied in its loaded state paired with the property type of the value.
1425    *
1426    * @param value The value to be defined as a default value.
1427    * @param type The type of the annotation property.
1428    * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
1429    */
1430    MethodDefinition.ReceiverTypeDefinition<U> defaultValue(Object value, Class<?> type);
1431   
1432    /**
1433    * A builder for optionally defining an implementation of a method.
1434    *
1435    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1436    */
 
1437    interface Optional<V> extends ImplementationDefinition<V>, Builder<V> {
1438    /* union type */
1439    }
1440   
1441    /**
1442    * An abstract base implementation for a builder optionally defining an implementation of a method.
1443    *
1444    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1445    */
 
1446    abstract class AbstractBase<V> implements ImplementationDefinition<V> {
1447   
 
1448  1 toggle @Override
1449    public MethodDefinition.ReceiverTypeDefinition<V> defaultValue(Object value, Class<?> type) {
1450  1 return defaultValue(AnnotationDescription.ForLoadedAnnotation.describe(value, new TypeDescription.ForLoadedType(type)));
1451    }
1452    }
1453    }
1454   
1455    /**
1456    * A builder for defining an implementation of a method and optionally defining a type variable.
1457    *
1458    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1459    */
 
1460    interface TypeVariableDefinition<U> extends ImplementationDefinition<U> {
1461   
1462    /**
1463    * Defines a method variable to be declared by the currently defined method. The defined method variable does not define any bounds.
1464    *
1465    * @param symbol The symbol of the type variable.
1466    * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
1467    */
1468    Annotatable<U> typeVariable(String symbol);
1469   
1470    /**
1471    * Defines a method variable to be declared by the currently defined method.
1472    *
1473    * @param symbol The symbol of the type variable.
1474    * @param bound The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
1475    * if a bound type should be equal to the currently instrumented type.
1476    * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
1477    */
1478    Annotatable<U> typeVariable(String symbol, Type... bound);
1479   
1480    /**
1481    * Defines a method variable to be declared by the currently defined method.
1482    *
1483    * @param symbol The symbol of the type variable.
1484    * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
1485    * if a bound type should be equal to the currently instrumented type.
1486    * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
1487    */
1488    Annotatable<U> typeVariable(String symbol, List<? extends Type> bounds);
1489   
1490    /**
1491    * Defines a method variable to be declared by the currently defined method.
1492    *
1493    * @param symbol The symbol of the type variable.
1494    * @param bound The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
1495    * if a bound type should be equal to the currently instrumented type.
1496    * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
1497    */
1498    Annotatable<U> typeVariable(String symbol, TypeDefinition... bound);
1499   
1500    /**
1501    * Defines a method variable to be declared by the currently defined method.
1502    *
1503    * @param symbol The symbol of the type variable.
1504    * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
1505    * if a bound type should be equal to the currently instrumented type.
1506    * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
1507    */
1508    Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
1509   
1510    /**
1511    * A builder for optionally defining an annotation for a type variable.
1512    *
1513    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1514    */
 
1515    interface Annotatable<V> extends TypeVariableDefinition<V> {
1516   
1517    /**
1518    * Annotates the previously defined type variable with the supplied annotations.
1519    *
1520    * @param annotation The annotations to declare on the previously defined type variable.
1521    * @return A new builder that is equal to this builder but with the given annotations declared
1522    * on the previously defined type variable.
1523    */
1524    Annotatable<V> annotateTypeVariable(Annotation... annotation);
1525   
1526    /**
1527    * Annotates the previously defined type variable with the supplied annotations.
1528    *
1529    * @param annotations The annotations to declare on the previously defined type variable.
1530    * @return A new builder that is equal to this builder but with the given annotations declared
1531    * on the previously defined type variable.
1532    */
1533    Annotatable<V> annotateTypeVariable(List<? extends Annotation> annotations);
1534   
1535    /**
1536    * Annotates the previously defined type variable with the supplied annotations.
1537    *
1538    * @param annotation The annotations to declare on the previously defined type variable.
1539    * @return A new builder that is equal to this builder but with the given annotations declared
1540    * on the previously defined type variable.
1541    */
1542    Annotatable<V> annotateTypeVariable(AnnotationDescription... annotation);
1543   
1544    /**
1545    * Annotates the previously defined type variable with the supplied annotations.
1546    *
1547    * @param annotations The annotations to declare on the previously defined type variable.
1548    * @return A new builder that is equal to this builder but with the given annotations declared
1549    * on the previously defined type variable.
1550    */
1551    Annotatable<V> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
1552   
1553    /**
1554    * An abstract base implementation for defining an annotation on a parameter.
1555    *
1556    * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
1557    */
 
1558    abstract class AbstractBase<W> extends TypeVariableDefinition.AbstractBase<W> implements Annotatable<W> {
1559   
 
1560  0 toggle @Override
1561    public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(Annotation... annotation) {
1562  0 return annotateTypeVariable(Arrays.asList(annotation));
1563    }
1564   
 
1565  0 toggle @Override
1566    public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(List<? extends Annotation> annotations) {
1567  0 return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
1568    }
1569   
 
1570  12 toggle @Override
1571    public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(AnnotationDescription... annotation) {
1572  12 return annotateTypeVariable(Arrays.asList(annotation));
1573    }
1574   
1575    /**
1576    * An adapter implementation for an annotatable type variable definition.
1577    *
1578    * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
1579    */
 
1580    protected abstract static class Adapter<X> extends TypeVariableDefinition.Annotatable.AbstractBase<X> {
1581   
 
1582  3 toggle @Override
1583    public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
1584  3 return materialize().typeVariable(symbol, bounds);
1585    }
1586   
 
1587  6 toggle @Override
1588    public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
1589  6 return materialize().intercept(implementation);
1590    }
1591   
 
1592  9 toggle @Override
1593    public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
1594  9 return materialize().withoutCode();
1595    }
1596   
 
1597  0 toggle @Override
1598    public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(Object value) {
1599  0 return materialize().defaultValue(value);
1600    }
1601   
 
1602  0 toggle @Override
1603    public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(Object value, Class<?> type) {
1604  0 return materialize().defaultValue(value, type);
1605    }
1606   
1607    /**
1608    * Materializes this instance as a parameter definition with the currently defined properties.
1609    *
1610    * @return A parameter definition with the currently defined properties.
1611    */
1612    protected abstract MethodDefinition.ParameterDefinition<X> materialize();
1613    }
1614   
1615    }
1616    }
1617   
1618    /**
1619    * An abstract base implementation for defining an implementation of a method and optionally definign a type variable.
1620    *
1621    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1622    */
 
1623    abstract class AbstractBase<V> extends ImplementationDefinition.AbstractBase<V> implements TypeVariableDefinition<V> {
1624   
 
1625  3 toggle @Override
1626    public Annotatable<V> typeVariable(String symbol) {
1627  3 return typeVariable(symbol, Collections.singletonList(Object.class));
1628    }
1629   
 
1630  6 toggle @Override
1631    public Annotatable<V> typeVariable(String symbol, Type... bound) {
1632  6 return typeVariable(symbol, Arrays.asList(bound));
1633    }
1634   
 
1635  9 toggle @Override
1636    public Annotatable<V> typeVariable(String symbol, List<? extends Type> bounds) {
1637  9 return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
1638    }
1639   
 
1640  9 toggle @Override
1641    public Annotatable<V> typeVariable(String symbol, TypeDefinition... bound) {
1642  9 return typeVariable(symbol, Arrays.asList(bound));
1643    }
1644    }
1645    }
1646   
1647    /**
1648    * A builder for defining an implementation of a method and optionally defining a type variable or thrown exception.
1649    *
1650    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1651    */
 
1652    interface ExceptionDefinition<U> extends TypeVariableDefinition<U> {
1653   
1654    /**
1655    * Defines a method variable to be declared by the currently defined method.
1656    *
1657    * @param type The type of the exception being declared by the currently defined method.
1658    * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
1659    */
1660    ExceptionDefinition<U> throwing(Type... type);
1661   
1662    /**
1663    * Defines a method variable to be declared by the currently defined method.
1664    *
1665    * @param types The type of the exception being declared by the currently defined method.
1666    * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
1667    */
1668    ExceptionDefinition<U> throwing(List<? extends Type> types);
1669   
1670    /**
1671    * Defines a method variable to be declared by the currently defined method.
1672    *
1673    * @param type The type of the exception being declared by the currently defined method.
1674    * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
1675    */
1676    ExceptionDefinition<U> throwing(TypeDefinition... type);
1677   
1678    /**
1679    * Defines a method variable to be declared by the currently defined method.
1680    *
1681    * @param types The type of the exception being declared by the currently defined method.
1682    * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
1683    */
1684    ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types);
1685   
1686    /**
1687    * An abstract base implementation for defining an implementation of a method and optionally definign a type variable or thrown exception.
1688    *
1689    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1690    */
 
1691    abstract class AbstractBase<V> extends TypeVariableDefinition.AbstractBase<V> implements ExceptionDefinition<V> {
1692   
 
1693  15 toggle @Override
1694    public ExceptionDefinition<V> throwing(Type... type) {
1695  15 return throwing(Arrays.asList(type));
1696    }
1697   
 
1698  15 toggle @Override
1699    public ExceptionDefinition<V> throwing(List<? extends Type> types) {
1700  15 return throwing(new TypeList.Generic.ForLoadedTypes(types));
1701    }
1702   
 
1703  3 toggle @Override
1704    public ExceptionDefinition<V> throwing(TypeDefinition... type) {
1705  3 return throwing(Arrays.asList(type));
1706    }
1707    }
1708    }
1709   
1710    /**
1711    * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
1712    *
1713    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1714    */
 
1715    interface ParameterDefinition<U> extends ExceptionDefinition<U> {
1716   
1717    /**
1718    * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
1719    *
1720    * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
1721    * should be equal to the currently instrumented type.
1722    * @param name The parameter's name.
1723    * @param modifierContributor The parameter's modifiers.
1724    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
1725    */
1726    Annotatable<U> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor);
1727   
1728    /**
1729    * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
1730    *
1731    * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
1732    * should be equal to the currently instrumented type.
1733    * @param name The parameter's name.
1734    * @param modifierContributors The parameter's modifiers.
1735    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
1736    */
1737    Annotatable<U> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
1738   
1739    /**
1740    * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
1741    *
1742    * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
1743    * should be equal to the currently instrumented type.
1744    * @param name The parameter's name.
1745    * @param modifiers The parameter's modifiers.
1746    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
1747    */
1748    Annotatable<U> withParameter(Type type, String name, int modifiers);
1749   
1750    /**
1751    * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
1752    *
1753    * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
1754    * should be equal to the currently instrumented type.
1755    * @param name The parameter's name.
1756    * @param modifierContributor The parameter's modifiers.
1757    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
1758    */
1759    Annotatable<U> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor);
1760   
1761    /**
1762    * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
1763    *
1764    * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
1765    * should be equal to the currently instrumented type.
1766    * @param name The parameter's name.
1767    * @param modifierContributors The parameter's modifiers.
1768    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
1769    */
1770    Annotatable<U> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
1771   
1772    /**
1773    * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
1774    *
1775    * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
1776    * should be equal to the currently instrumented type.
1777    * @param name The parameter's name.
1778    * @param modifiers The parameter's modifiers.
1779    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
1780    */
1781    Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers);
1782   
1783    /**
1784    * A builder for optionally defining an annotation on a parameter.
1785    *
1786    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1787    */
 
1788    interface Annotatable<V> extends ParameterDefinition<V> {
1789   
1790    /**
1791    * Annotates the previously defined parameter with the specifed annotations.
1792    *
1793    * @param annotation The annotations to declare on the previously defined parameter.
1794    * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
1795    * the specified annotations.
1796    */
1797    Annotatable<V> annotateParameter(Annotation... annotation);
1798   
1799    /**
1800    * Annotates the previously defined parameter with the specifed annotations.
1801    *
1802    * @param annotations The annotations to declare on the previously defined parameter.
1803    * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
1804    * the specified annotations.
1805    */
1806    Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
1807   
1808    /**
1809    * Annotates the previously defined parameter with the specifed annotations.
1810    *
1811    * @param annotation The annotations to declare on the previously defined parameter.
1812    * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
1813    * the specified annotations.
1814    */
1815    Annotatable<V> annotateParameter(AnnotationDescription... annotation);
1816   
1817    /**
1818    * Annotates the previously defined parameter with the specifed annotations.
1819    *
1820    * @param annotations The annotations to declare on the previously defined parameter.
1821    * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
1822    * the specified annotations.
1823    */
1824    Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
1825   
1826    /**
1827    * An abstract base implementation for defining an annotation on a parameter.
1828    *
1829    * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
1830    */
 
1831    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Annotatable<W> {
1832   
 
1833  0 toggle @Override
1834    public ParameterDefinition.Annotatable<W> annotateParameter(Annotation... annotation) {
1835  0 return annotateParameter(Arrays.asList(annotation));
1836    }
1837   
 
1838  0 toggle @Override
1839    public ParameterDefinition.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
1840  0 return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
1841    }
1842   
 
1843  0 toggle @Override
1844    public ParameterDefinition.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
1845  0 return annotateParameter(Arrays.asList(annotation));
1846    }
1847   
1848    /**
1849    * An adapter implementation for defining an annotation on a parameter.
1850    *
1851    * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
1852    */
 
1853    protected abstract static class Adapter<X> extends ParameterDefinition.Annotatable.AbstractBase<X> {
1854   
 
1855  0 toggle @Override
1856    public ParameterDefinition.Annotatable<X> withParameter(TypeDefinition type, String name, int modifiers) {
1857  0 return materialize().withParameter(type, name, modifiers);
1858    }
1859   
 
1860  6 toggle @Override
1861    public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
1862  6 return materialize().throwing(types);
1863    }
1864   
 
1865  0 toggle @Override
1866    public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
1867  0 return materialize().typeVariable(symbol, bounds);
1868    }
1869   
 
1870  0 toggle @Override
1871    public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
1872  0 return materialize().intercept(implementation);
1873    }
1874   
 
1875  0 toggle @Override
1876    public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
1877  0 return materialize().withoutCode();
1878    }
1879   
 
1880  0 toggle @Override
1881    public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(Object value) {
1882  0 return materialize().defaultValue(value);
1883    }
1884   
 
1885  0 toggle @Override
1886    public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(Object value, Class<?> type) {
1887  0 return materialize().defaultValue(value, type);
1888    }
1889   
1890    /**
1891    * Materializes this instance as a parameter definition with the currently defined properties.
1892    *
1893    * @return A parameter definition with the currently defined properties.
1894    */
1895    protected abstract MethodDefinition.ParameterDefinition<X> materialize();
1896    }
1897    }
1898    }
1899   
1900    /**
1901    * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or a parameter type.
1902    *
1903    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1904    */
 
1905    interface Simple<V> extends ExceptionDefinition<V> {
1906   
1907    /**
1908    * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
1909    *
1910    * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
1911    * should be equal to the currently instrumented type.
1912    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
1913    */
1914    Annotatable<V> withParameter(Type type);
1915   
1916    /**
1917    * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
1918    *
1919    * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
1920    * should be equal to the currently instrumented type.
1921    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
1922    */
1923    Annotatable<V> withParameter(TypeDefinition type);
1924   
1925    /**
1926    * A builder for optionally defining an annotation on a parameter.
1927    *
1928    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1929    */
 
1930    interface Annotatable<V> extends Simple<V> {
1931   
1932    /**
1933    * Annotates the previously defined parameter with the specifed annotations.
1934    *
1935    * @param annotation The annotations to declare on the previously defined parameter.
1936    * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
1937    * the specified annotations.
1938    */
1939    Annotatable<V> annotateParameter(Annotation... annotation);
1940   
1941    /**
1942    * Annotates the previously defined parameter with the specifed annotations.
1943    *
1944    * @param annotations The annotations to declare on the previously defined parameter.
1945    * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
1946    * the specified annotations.
1947    */
1948    Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
1949   
1950    /**
1951    * Annotates the previously defined parameter with the specifed annotations.
1952    *
1953    * @param annotation The annotations to declare on the previously defined parameter.
1954    * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
1955    * the specified annotations.
1956    */
1957    Annotatable<V> annotateParameter(AnnotationDescription... annotation);
1958   
1959    /**
1960    * Annotates the previously defined parameter with the specifed annotations.
1961    *
1962    * @param annotations The annotations to declare on the previously defined parameter.
1963    * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
1964    * the specified annotations.
1965    */
1966    Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
1967   
1968    /**
1969    * An abstract base implementation of a simple parameter definition.
1970    *
1971    * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
1972    */
 
1973    abstract class AbstractBase<W> extends Simple.AbstractBase<W> implements Annotatable<W> {
1974   
 
1975  0 toggle @Override
1976    public Simple.Annotatable<W> annotateParameter(Annotation... annotation) {
1977  0 return annotateParameter(Arrays.asList(annotation));
1978    }
1979   
 
1980  0 toggle @Override
1981    public Simple.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
1982  0 return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
1983    }
1984   
 
1985  0 toggle @Override
1986    public Simple.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
1987  0 return annotateParameter(Arrays.asList(annotation));
1988    }
1989   
1990    /**
1991    * An adapter implementation of a simple parameter definition.
1992    *
1993    * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
1994    */
 
1995    protected abstract static class Adapter<X> extends Simple.Annotatable.AbstractBase<X> {
1996   
 
1997  288 toggle @Override
1998    public Simple.Annotatable<X> withParameter(TypeDefinition type) {
1999  288 return materialize().withParameter(type);
2000    }
2001   
 
2002  3 toggle @Override
2003    public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
2004  3 return materialize().throwing(types);
2005    }
2006   
 
2007  0 toggle @Override
2008    public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2009  0 return materialize().typeVariable(symbol, bounds);
2010    }
2011   
 
2012  250 toggle @Override
2013    public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2014  250 return materialize().intercept(implementation);
2015    }
2016   
 
2017  5 toggle @Override
2018    public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2019  5 return materialize().withoutCode();
2020    }
2021   
 
2022  0 toggle @Override
2023    public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(Object value) {
2024  0 return materialize().defaultValue(value);
2025    }
2026   
 
2027  0 toggle @Override
2028    public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(Object value, Class<?> type) {
2029  0 return materialize().defaultValue(value, type);
2030    }
2031   
2032    /**
2033    * Materializes this instance as a simple parameter definition with the currently defined properties.
2034    *
2035    * @return A simple parameter definition with the currently defined properties.
2036    */
2037    protected abstract MethodDefinition.ParameterDefinition.Simple<X> materialize();
2038    }
2039    }
2040    }
2041   
2042    /**
2043    * An abstract base implementation of an exception definition.
2044    *
2045    * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2046    */
 
2047    abstract class AbstractBase<W> extends ExceptionDefinition.AbstractBase<W> implements Simple<W> {
2048   
 
2049  0 toggle @Override
2050    public Simple.Annotatable<W> withParameter(Type type) {
2051  0 return withParameter(TypeDefinition.Sort.describe(type));
2052    }
2053    }
2054    }
2055   
2056    /**
2057    * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
2058    * Implementations allow for the <i>one-by-one</i> definition of parameters what gives opportunity to annotate parameters in a fluent
2059    * style. Doing so, it is optionally possible to define parameter names and modifiers. This can be done for either all or no parameters.
2060    * Alternatively, parameters without annotations, names or modifiers can be defined by a single step.
2061    *
2062    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2063    */
 
2064    interface Initial<V> extends ParameterDefinition<V>, Simple<V> {
2065   
2066    /**
2067    * Defines the specified parameters for the currently defined method.
2068    *
2069    * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2070    * should be equal to the currently instrumented type.
2071    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2072    */
2073    ExceptionDefinition<V> withParameters(Type... type);
2074   
2075    /**
2076    * Defines the specified parameters for the currently defined method.
2077    *
2078    * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2079    * should be equal to the currently instrumented type.
2080    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2081    */
2082    ExceptionDefinition<V> withParameters(List<? extends Type> types);
2083   
2084    /**
2085    * Defines the specified parameters for the currently defined method.
2086    *
2087    * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2088    * should be equal to the currently instrumented type.
2089    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2090    */
2091    ExceptionDefinition<V> withParameters(TypeDefinition... type);
2092   
2093    /**
2094    * Defines the specified parameters for the currently defined method.
2095    *
2096    * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2097    * should be equal to the currently instrumented type.
2098    * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2099    */
2100    ExceptionDefinition<V> withParameters(Collection<? extends TypeDefinition> types);
2101   
2102    /**
2103    * An abstract base implementation for an initial parameter definition.
2104    *
2105    * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2106    */
 
2107    abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Initial<W> {
2108   
 
2109  0 toggle @Override
2110    public Simple.Annotatable<W> withParameter(Type type) {
2111  0 return withParameter(TypeDefinition.Sort.describe(type));
2112    }
2113   
 
2114  8 toggle @Override
2115    public ExceptionDefinition<W> withParameters(Type... type) {
2116  8 return withParameters(Arrays.asList(type));
2117    }
2118   
 
2119  8 toggle @Override
2120    public ExceptionDefinition<W> withParameters(List<? extends Type> types) {
2121  8 return withParameters(new TypeList.Generic.ForLoadedTypes(types));
2122    }
2123   
 
2124  3 toggle @Override
2125    public ExceptionDefinition<W> withParameters(TypeDefinition... type) {
2126  3 return withParameters(Arrays.asList(type));
2127    }
2128   
 
2129  277 toggle @Override
2130    public ExceptionDefinition<W> withParameters(Collection<? extends TypeDefinition> types) {
2131  277 ParameterDefinition.Simple<W> parameterDefinition = this;
2132  277 for (TypeDefinition type : types) {
2133  546 parameterDefinition = parameterDefinition.withParameter(type);
2134    }
2135  277 return parameterDefinition;
2136    }
2137    }
2138    }
2139   
2140    /**
2141    * An abstract base implementation for defining an implementation of a method and optionally definign a type variable, thrown exception or parameter type.
2142    *
2143    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2144    */
 
2145    abstract class AbstractBase<V> extends ExceptionDefinition.AbstractBase<V> implements ParameterDefinition<V> {
2146   
 
2147  6 toggle @Override
2148    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor) {
2149  6 return withParameter(type, name, Arrays.asList(modifierContributor));
2150    }
2151   
 
2152  6 toggle @Override
2153    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
2154  6 return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
2155    }
2156   
 
2157  6 toggle @Override
2158    public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, int modifiers) {
2159  6 return withParameter(TypeDefinition.Sort.describe(type), name, modifiers);
2160    }
2161   
 
2162  0 toggle @Override
2163    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor) {
2164  0 return withParameter(type, name, Arrays.asList(modifierContributor));
2165    }
2166   
 
2167  0 toggle @Override
2168    public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
2169  0 return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
2170    }
2171    }
2172    }
2173   
2174    /**
2175    * An abstract base implementation of a method definition.
2176    *
2177    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2178    */
 
2179    abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements MethodDefinition<U> {
2180   
 
2181  1 toggle @Override
2182    public MethodDefinition<U> annotateMethod(Annotation... annotation) {
2183  1 return annotateMethod(Arrays.asList(annotation));
2184    }
2185   
 
2186  1 toggle @Override
2187    public MethodDefinition<U> annotateMethod(List<? extends Annotation> annotations) {
2188  1 return annotateMethod(new AnnotationList.ForLoadedAnnotations(annotations));
2189    }
2190   
 
2191  1 toggle @Override
2192    public MethodDefinition<U> annotateMethod(AnnotationDescription... annotation) {
2193  1 return annotateMethod(Arrays.asList(annotation));
2194    }
2195   
 
2196  0 toggle @Override
2197    public MethodDefinition<U> annotateParameter(int index, Annotation... annotation) {
2198  0 return annotateParameter(index, Arrays.asList(annotation));
2199    }
2200   
 
2201  0 toggle @Override
2202    public MethodDefinition<U> annotateParameter(int index, List<? extends Annotation> annotations) {
2203  0 return annotateParameter(index, new AnnotationList.ForLoadedAnnotations(annotations));
2204    }
2205   
 
2206  0 toggle @Override
2207    public MethodDefinition<U> annotateParameter(int index, AnnotationDescription... annotation) {
2208  0 return annotateParameter(index, Arrays.asList(annotation));
2209    }
2210   
2211    /**
2212    * An adapter implementation of a method definition.
2213    *
2214    * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2215    */
 
2216    protected abstract static class Adapter<V> extends MethodDefinition.ReceiverTypeDefinition.AbstractBase<V> {
2217   
2218    /**
2219    * The handler that determines how a method is implemented.
2220    */
2221    protected final MethodRegistry.Handler handler;
2222   
2223    /**
2224    * The method attribute appender factory to apply onto the method that is currently being implemented.
2225    */
2226    protected final MethodAttributeAppender.Factory methodAttributeAppenderFactory;
2227   
2228    /**
2229    * The method transformer to apply onto the method that is currently being implemented.
2230    */
2231    protected final MethodTransformer methodTransformer;
2232   
2233    /**
2234    * Creates a new adapter for a method definition.
2235    *
2236    * @param handler The handler that determines how a method is implemented.
2237    * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
2238    * @param methodTransformer The method transformer to apply onto the method that is currently being implemented.
2239    */
 
2240  1326 toggle protected Adapter(MethodRegistry.Handler handler, MethodAttributeAppender.Factory methodAttributeAppenderFactory, MethodTransformer methodTransformer) {
2241  1326 this.handler = handler;
2242  1326 this.methodAttributeAppenderFactory = methodAttributeAppenderFactory;
2243  1326 this.methodTransformer = methodTransformer;
2244    }
2245   
 
2246  0 toggle @Override
2247    public MethodDefinition<V> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory) {
2248  0 return materialize(handler, new MethodAttributeAppender.Factory.Compound(this.methodAttributeAppenderFactory, methodAttributeAppenderFactory), methodTransformer);
2249    }
2250   
 
2251  5 toggle @Override
2252    public MethodDefinition<V> transform(MethodTransformer methodTransformer) {
2253  5 return materialize(handler, methodAttributeAppenderFactory, new MethodTransformer.Compound(this.methodTransformer, methodTransformer));
2254    }
2255   
2256    /**
2257    * Materializes the current builder as a method definition.
2258    *
2259    * @param handler The handler that determines how a method is implemented.
2260    * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
2261    * @param methodTransformer The method transformer to apply onto the method that is currently being implemented.
2262    * @return Returns a method definition for the supplied properties.
2263    */
2264    protected abstract MethodDefinition<V> materialize(MethodRegistry.Handler handler, MethodAttributeAppender.Factory methodAttributeAppenderFactory, MethodTransformer methodTransformer);
2265   
 
2266  16 toggle @Override
2267    public boolean equals(Object other) {
2268  16 if (this == other) return true;
2269  16 if (other == null || getClass() != other.getClass()) return false;
2270  16 Adapter<?> adapter = (Adapter<?>) other;
2271  16 return handler.equals(adapter.handler)
2272    && methodAttributeAppenderFactory.equals(adapter.methodAttributeAppenderFactory)
2273    && methodTransformer.equals(adapter.methodTransformer);
2274    }
2275   
 
2276  20 toggle @Override
2277    public int hashCode() {
2278  20 int result = handler.hashCode();
2279  20 result = 31 * result + methodAttributeAppenderFactory.hashCode();
2280  20 result = 31 * result + methodTransformer.hashCode();
2281  20 return result;
2282    }
2283    }
2284    }
2285    }
2286   
2287    /**
2288    * An abstract base implementation of a dynamic type builder.
2289    *
2290    * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
2291    */
 
2292    abstract class AbstractBase<S> implements Builder<S> {
2293   
 
2294  1 toggle @Override
2295    public Builder<S> annotateType(Annotation... annotation) {
2296  1 return annotateType(Arrays.asList(annotation));
2297    }
2298   
 
2299  1 toggle @Override
2300    public Builder<S> annotateType(List<? extends Annotation> annotations) {
2301  1 return annotateType(new AnnotationList.ForLoadedAnnotations(annotations));
2302    }
2303   
 
2304  3 toggle @Override
2305    public Builder<S> annotateType(AnnotationDescription... annotation) {
2306  3 return annotateType(Arrays.asList(annotation));
2307    }
2308   
 
2309  291 toggle @Override
2310    public Builder<S> modifiers(ModifierContributor.ForType... modifierContributor) {
2311  291 return modifiers(Arrays.asList(modifierContributor));
2312    }
2313   
 
2314  291 toggle @Override
2315    public Builder<S> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors) {
2316  291 return modifiers(ModifierContributor.Resolver.of(modifierContributors).resolve());
2317    }
2318   
 
2319  25 toggle @Override
2320    public Builder<S> merge(ModifierContributor.ForType... modifierContributor) {
2321  25 return merge(Arrays.asList(modifierContributor));
2322    }
2323   
 
2324  836 toggle @Override
2325    public MethodDefinition.ImplementationDefinition.Optional<S> implement(Type... interfaceType) {
2326  836 return implement(Arrays.asList(interfaceType));
2327    }
2328   
 
2329  872 toggle @Override
2330    public MethodDefinition.ImplementationDefinition.Optional<S> implement(List<? extends Type> interfaceTypes) {
2331  872 return implement(new TypeList.Generic.ForLoadedTypes(interfaceTypes));
2332    }
2333   
 
2334  5 toggle @Override
2335    public MethodDefinition.ImplementationDefinition.Optional<S> implement(TypeDefinition... interfaceType) {
2336  5 return implement(Arrays.asList(interfaceType));
2337    }
2338   
 
2339  6 toggle @Override
2340    public TypeVariableDefinition<S> typeVariable(String symbol) {
2341  6 return typeVariable(symbol, TypeDescription.Generic.OBJECT);
2342    }
2343   
 
2344  3 toggle @Override
2345    public TypeVariableDefinition<S> typeVariable(String symbol, Type... bound) {
2346  3 return typeVariable(symbol, Arrays.asList(bound));
2347    }
2348   
 
2349  3 toggle @Override
2350    public TypeVariableDefinition<S> typeVariable(String symbol, List<? extends Type> bounds) {
2351  3 return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
2352    }
2353   
 
2354  17 toggle @Override
2355    public TypeVariableDefinition<S> typeVariable(String symbol, TypeDefinition... bound) {
2356  17 return typeVariable(symbol, Arrays.asList(bound));
2357    }
2358   
 
2359  63 toggle @Override
2360    public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor) {
2361  63 return defineField(name, type, Arrays.asList(modifierContributor));
2362    }
2363   
 
2364  63 toggle @Override
2365    public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
2366  63 return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
2367    }
2368   
 
2369  63 toggle @Override
2370    public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, int modifiers) {
2371  63 return defineField(name, TypeDefinition.Sort.describe(type), modifiers);
2372    }
2373   
 
2374  510 toggle @Override
2375    public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor) {
2376  510 return defineField(name, type, Arrays.asList(modifierContributor));
2377    }
2378   
 
2379  510 toggle @Override
2380    public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
2381  510 return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
2382    }
2383   
 
2384  0 toggle @Override
2385    public FieldDefinition.Optional.Valuable<S> define(Field field) {
2386  0 return define(new FieldDescription.ForLoadedField(field));
2387    }
2388   
 
2389  0 toggle @Override
2390    public FieldDefinition.Optional.Valuable<S> define(FieldDescription field) {
2391  0 return defineField(field.getName(), field.getType(), field.getModifiers());
2392    }
2393   
 
2394  3 toggle @Override
2395    public FieldDefinition.Optional<S> serialVersionUid(long serialVersionUid) {
2396  3 return defineField("serialVersionUID", long.class, Visibility.PRIVATE, FieldManifestation.FINAL, Ownership.STATIC).value(serialVersionUid);
2397    }
2398   
 
2399  9 toggle @Override
2400    public FieldDefinition.Valuable<S> field(ElementMatcher<? super FieldDescription> matcher) {
2401  9 return field(new LatentMatcher.Resolved<FieldDescription>(matcher));
2402    }
2403   
 
2404  6 toggle @Override
2405    public Builder<S> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
2406  6 return ignoreAlso(new LatentMatcher.Resolved<MethodDescription>(ignoredMethods));
2407    }
2408   
 
2409  117 toggle @Override
2410    public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor) {
2411  117 return defineMethod(name, returnType, Arrays.asList(modifierContributor));
2412    }
2413   
 
2414  117 toggle @Override
2415    public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
2416  117 return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
2417    }
2418   
 
2419  117 toggle @Override
2420    public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, int modifiers) {
2421  117 return defineMethod(name, TypeDefinition.Sort.describe(returnType), modifiers);
2422    }
2423   
 
2424  24 toggle @Override
2425    public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor) {
2426  24 return defineMethod(name, returnType, Arrays.asList(modifierContributor));
2427    }
2428   
 
2429  24 toggle @Override
2430    public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
2431  24 return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
2432    }
2433   
 
2434  253 toggle @Override
2435    public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(ModifierContributor.ForMethod... modifierContributor) {
2436  253 return defineConstructor(Arrays.asList(modifierContributor));
2437    }
2438   
 
2439  253 toggle @Override
2440    public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
2441  253 return defineConstructor(ModifierContributor.Resolver.of(modifierContributors).resolve());
2442    }
2443   
 
2444  0 toggle @Override
2445    public MethodDefinition.ImplementationDefinition<S> define(Method method) {
2446  0 return define(new MethodDescription.ForLoadedMethod(method));
2447    }
2448   
 
2449  0 toggle @Override
2450    public MethodDefinition.ImplementationDefinition<S> define(Constructor<?> constructor) {
2451  0 return define(new MethodDescription.ForLoadedConstructor(constructor));
2452    }
2453   
 
2454  0 toggle @Override
2455    public MethodDefinition.ImplementationDefinition<S> define(MethodDescription methodDescription) {
2456  0 MethodDefinition.ParameterDefinition.Initial<S> initialParameterDefinition = methodDescription.isConstructor()
2457    ? defineConstructor(methodDescription.getModifiers())
2458    : defineMethod(methodDescription.getInternalName(), methodDescription.getReturnType(), methodDescription.getModifiers());
2459  0 ParameterList<?> parameterList = methodDescription.getParameters();
2460  0 MethodDefinition.ExceptionDefinition<S> exceptionDefinition;
2461  0 if (parameterList.hasExplicitMetaData()) {
2462  0 MethodDefinition.ParameterDefinition<S> parameterDefinition = initialParameterDefinition;
2463  0 for (ParameterDescription parameter : parameterList) {
2464  0 parameterDefinition = parameterDefinition.withParameter(parameter.getType(), parameter.getName(), parameter.getModifiers());
2465    }
2466  0 exceptionDefinition = parameterDefinition;
2467    } else {
2468  0 exceptionDefinition = initialParameterDefinition.withParameters(parameterList.asTypeList());
2469    }
2470  0 MethodDefinition.TypeVariableDefinition<S> typeVariableDefinition = exceptionDefinition.throwing(methodDescription.getExceptionTypes());
2471  0 for (TypeDescription.Generic typeVariable : methodDescription.getTypeVariables()) {
2472  0 typeVariableDefinition = typeVariableDefinition.typeVariable(typeVariable.getSymbol(), typeVariable.getUpperBounds());
2473    }
2474  0 return typeVariableDefinition;
2475    }
2476   
 
2477  290 toggle @Override
2478    public MethodDefinition.ImplementationDefinition<S> method(ElementMatcher<? super MethodDescription> matcher) {
2479  290 return invokable(isMethod().and(matcher));
2480    }
2481   
 
2482  6 toggle @Override
2483    public MethodDefinition.ImplementationDefinition<S> constructor(ElementMatcher<? super MethodDescription> matcher) {
2484  6 return invokable(isConstructor().and(matcher));
2485    }
2486   
 
2487  903 toggle @Override
2488    public MethodDefinition.ImplementationDefinition<S> invokable(ElementMatcher<? super MethodDescription> matcher) {
2489  903 return invokable(new LatentMatcher.Resolved<MethodDescription>(matcher));
2490    }
2491   
2492    /**
2493    * A delegator for a dynamic type builder delegating all invocations to another dynamic type builder.
2494    *
2495    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2496    */
 
2497    public abstract static class Delegator<U> extends AbstractBase<U> {
2498   
 
2499  0 toggle @Override
2500    public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
2501  0 return materialize().visit(asmVisitorWrapper);
2502    }
2503   
 
2504  0 toggle @Override
2505    public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
2506  0 return materialize().initializer(loadedTypeInitializer);
2507    }
2508   
 
2509  0 toggle @Override
2510    public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
2511  0 return materialize().annotateType(annotations);
2512    }
2513   
 
2514  0 toggle @Override
2515    public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
2516  0 return materialize().attribute(typeAttributeAppender);
2517    }
2518   
 
2519  8 toggle @Override
2520    public Builder<U> modifiers(int modifiers) {
2521  8 return materialize().modifiers(modifiers);
2522    }
2523   
 
2524  0 toggle @Override
2525    public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
2526  0 return materialize().merge(modifierContributors);
2527    }
2528   
 
2529  36 toggle @Override
2530    public Builder<U> name(String name) {
2531  36 return materialize().name(name);
2532    }
2533   
 
2534  184 toggle @Override
2535    public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
2536  184 return materialize().implement(interfaceTypes);
2537    }
2538   
 
2539  55 toggle @Override
2540    public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
2541  55 return materialize().initializer(byteCodeAppender);
2542    }
2543   
 
2544  0 toggle @Override
2545    public Builder<U> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
2546  0 return materialize().ignoreAlso(ignoredMethods);
2547    }
2548   
 
2549  0 toggle @Override
2550    public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
2551  0 return materialize().ignoreAlso(ignoredMethods);
2552    }
2553   
 
2554  6 toggle @Override
2555    public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2556  6 return materialize().typeVariable(symbol, bounds);
2557    }
2558   
 
2559  514 toggle @Override
2560    public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
2561  514 return materialize().defineField(name, type, modifiers);
2562    }
2563   
 
2564  3 toggle @Override
2565    public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
2566  3 return materialize().field(matcher);
2567    }
2568   
 
2569  59 toggle @Override
2570    public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
2571  59 return materialize().defineMethod(name, returnType, modifiers);
2572    }
2573   
 
2574  209 toggle @Override
2575    public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
2576  209 return materialize().defineConstructor(modifiers);
2577    }
2578   
 
2579  520 toggle @Override
2580    public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
2581  520 return materialize().invokable(matcher);
2582    }
2583   
 
2584  1011 toggle @Override
2585    public DynamicType.Unloaded<U> make() {
2586  1011 return materialize().make();
2587    }
2588   
 
2589  0 toggle @Override
2590    public Unloaded<U> make(TypePool typePool) {
2591  0 return materialize().make(typePool);
2592    }
2593   
2594    /**
2595    * Creates a new builder that realizes the current state of the builder.
2596    *
2597    * @return A new builder that realizes the current state of the builder.
2598    */
2599    protected abstract Builder<U> materialize();
2600    }
2601   
2602    /**
2603    * An adapter implementation of a dynamic type builder.
2604    *
2605    * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2606    */
 
2607    public abstract static class Adapter<U> extends AbstractBase<U> {
2608   
2609    /**
2610    * The instrumented type to be created.
2611    */
2612    protected final InstrumentedType.WithFlexibleName instrumentedType;
2613   
2614    /**
2615    * The current field registry.
2616    */
2617    protected final FieldRegistry fieldRegistry;
2618   
2619    /**
2620    * The current method registry.
2621    */
2622    protected final MethodRegistry methodRegistry;
2623   
2624    /**
2625    * The type attribute appender to apply onto the instrumented type.
2626    */
2627    protected final TypeAttributeAppender typeAttributeAppender;
2628   
2629    /**
2630    * The ASM visitor wrapper to apply onto the class writer.
2631    */
2632    protected final AsmVisitorWrapper asmVisitorWrapper;
2633   
2634    /**
2635    * The class file version to define auxiliary types in.
2636    */
2637    protected final ClassFileVersion classFileVersion;
2638   
2639    /**
2640    * The naming strategy for auxiliary types to apply.
2641    */
2642    protected final AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy;
2643   
2644    /**
2645    * The annotation value filter factory to apply.
2646    */
2647    protected final AnnotationValueFilter.Factory annotationValueFilterFactory;
2648   
2649    /**
2650    * The annotation retention to apply.
2651    */
2652    protected final AnnotationRetention annotationRetention;
2653   
2654    /**
2655    * The implementation context factory to apply.
2656    */
2657    protected final Implementation.Context.Factory implementationContextFactory;
2658   
2659    /**
2660    * The method graph compiler to use.
2661    */
2662    protected final MethodGraph.Compiler methodGraphCompiler;
2663   
2664    /**
2665    * Determines if a type should be explicitly validated.
2666    */
2667    protected final TypeValidation typeValidation;
2668   
2669    /**
2670    * A matcher for identifying methods that should be excluded from instrumentation.
2671    */
2672    protected final LatentMatcher<? super MethodDescription> ignoredMethods;
2673   
2674    /**
2675    * Creates a new default type writer for creating a new type that is not based on an existing class file.
2676    *
2677    * @param instrumentedType The instrumented type to be created.
2678    * @param fieldRegistry The current field registry.
2679    * @param methodRegistry The current method registry.
2680    * @param typeAttributeAppender The type attribute appender to apply onto the instrumented type.
2681    * @param asmVisitorWrapper The ASM visitor wrapper to apply onto the class writer.
2682    * @param classFileVersion The class file version to define auxiliary types in.
2683    * @param auxiliaryTypeNamingStrategy The naming strategy for auxiliary types to apply.
2684    * @param annotationValueFilterFactory The annotation value filter factory to apply.
2685    * @param annotationRetention The annotation retention to apply.
2686    * @param implementationContextFactory The implementation context factory to apply.
2687    * @param methodGraphCompiler The method graph compiler to use.
2688    * @param typeValidation Determines if a type should be explicitly validated.
2689    * @param ignoredMethods A matcher for identifying methods that should be excluded from instrumentation.
2690    */
 
2691  5395 toggle protected Adapter(InstrumentedType.WithFlexibleName instrumentedType,
2692    FieldRegistry fieldRegistry,
2693    MethodRegistry methodRegistry,
2694    TypeAttributeAppender typeAttributeAppender,
2695    AsmVisitorWrapper asmVisitorWrapper,
2696    ClassFileVersion classFileVersion,
2697    AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
2698    AnnotationValueFilter.Factory annotationValueFilterFactory,
2699    AnnotationRetention annotationRetention,
2700    Implementation.Context.Factory implementationContextFactory,
2701    MethodGraph.Compiler methodGraphCompiler,
2702    TypeValidation typeValidation,
2703    LatentMatcher<? super MethodDescription> ignoredMethods) {
2704  5395 this.instrumentedType = instrumentedType;
2705  5395 this.fieldRegistry = fieldRegistry;
2706  5395 this.methodRegistry = methodRegistry;
2707  5395 this.typeAttributeAppender = typeAttributeAppender;
2708  5395 this.asmVisitorWrapper = asmVisitorWrapper;
2709  5395 this.classFileVersion = classFileVersion;
2710  5395 this.auxiliaryTypeNamingStrategy = auxiliaryTypeNamingStrategy;
2711  5395 this.annotationValueFilterFactory = annotationValueFilterFactory;
2712  5395 this.annotationRetention = annotationRetention;
2713  5395 this.implementationContextFactory = implementationContextFactory;
2714  5395 this.methodGraphCompiler = methodGraphCompiler;
2715  5395 this.typeValidation = typeValidation;
2716  5395 this.ignoredMethods = ignoredMethods;
2717    }
2718   
 
2719  573 toggle @Override
2720    public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
2721  573 return new FieldDefinitionAdapter(new FieldDescription.Token(name, modifiers, type.asGenericType()));
2722    }
2723   
 
2724  9 toggle @Override
2725    public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
2726  9 return new FieldMatchAdapter(matcher);
2727    }
2728   
 
2729  141 toggle @Override
2730    public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
2731  141 return new MethodDefinitionAdapter(new MethodDescription.Token(name, modifiers, returnType.asGenericType()));
2732    }
2733   
 
2734  253 toggle @Override
2735    public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
2736  253 return new MethodDefinitionAdapter(new MethodDescription.Token(modifiers));
2737    }
2738   
 
2739  903 toggle @Override
2740    public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
2741  903 return new MethodMatchAdapter(matcher);
2742    }
2743   
 
2744  885 toggle @Override
2745    public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
2746  885 return new OptionalMethodMatchAdapter(new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(interfaceTypes)));
2747    }
2748   
 
2749  6 toggle @Override
2750    @SuppressWarnings("unchecked") // In absence of @SafeVarargs for Java 6
2751    public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
2752  6 return materialize(instrumentedType,
2753    fieldRegistry,
2754    methodRegistry,
2755    typeAttributeAppender,
2756    asmVisitorWrapper,
2757    classFileVersion,
2758    auxiliaryTypeNamingStrategy,
2759    annotationValueFilterFactory,
2760    annotationRetention,
2761    implementationContextFactory,
2762    methodGraphCompiler,
2763    typeValidation,
2764    new LatentMatcher.Compound(this.ignoredMethods, ignoredMethods));
2765    }
2766   
 
2767  67 toggle @Override
2768    public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
2769  67 return materialize(instrumentedType.withInitializer(byteCodeAppender),
2770    fieldRegistry,
2771    methodRegistry,
2772    typeAttributeAppender,
2773    asmVisitorWrapper,
2774    classFileVersion,
2775    auxiliaryTypeNamingStrategy,
2776    annotationValueFilterFactory,
2777    annotationRetention,
2778    implementationContextFactory,
2779    methodGraphCompiler,
2780    typeValidation,
2781    ignoredMethods);
2782    }
2783   
 
2784  0 toggle @Override
2785    public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
2786  0 return materialize(instrumentedType.withInitializer(loadedTypeInitializer),
2787    fieldRegistry,
2788    methodRegistry,
2789    typeAttributeAppender,
2790    asmVisitorWrapper,
2791    classFileVersion,
2792    auxiliaryTypeNamingStrategy,
2793    annotationValueFilterFactory,
2794    annotationRetention,
2795    implementationContextFactory,
2796    methodGraphCompiler,
2797    typeValidation,
2798    ignoredMethods);
2799    }
2800   
 
2801  299 toggle @Override
2802    public Builder<U> name(String name) {
2803  299 return materialize(instrumentedType.withName(name),
2804    fieldRegistry,
2805    methodRegistry,
2806    typeAttributeAppender,
2807    asmVisitorWrapper,
2808    classFileVersion,
2809    auxiliaryTypeNamingStrategy,
2810    annotationValueFilterFactory,
2811    annotationRetention,
2812    implementationContextFactory,
2813    methodGraphCompiler,
2814    typeValidation,
2815    ignoredMethods);
2816    }
2817   
 
2818  307 toggle @Override
2819    public Builder<U> modifiers(int modifiers) {
2820  307 return materialize(instrumentedType.withModifiers(modifiers),
2821    fieldRegistry,
2822    methodRegistry,
2823    typeAttributeAppender,
2824    asmVisitorWrapper,
2825    classFileVersion,
2826    auxiliaryTypeNamingStrategy,
2827    annotationValueFilterFactory,
2828    annotationRetention,
2829    implementationContextFactory,
2830    methodGraphCompiler,
2831    typeValidation,
2832    ignoredMethods);
2833    }
2834   
 
2835  25 toggle @Override
2836    public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
2837  25 return materialize(instrumentedType.withModifiers(ModifierContributor.Resolver.of(modifierContributors).resolve(instrumentedType.getModifiers())),
2838    fieldRegistry,
2839    methodRegistry,
2840    typeAttributeAppender,
2841    asmVisitorWrapper,
2842    classFileVersion,
2843    auxiliaryTypeNamingStrategy,
2844    annotationValueFilterFactory,
2845    annotationRetention,
2846    implementationContextFactory,
2847    methodGraphCompiler,
2848    typeValidation,
2849    ignoredMethods);
2850    }
2851   
 
2852  20 toggle @Override
2853    public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2854  20 return new TypeVariableDefinitionAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
2855    }
2856   
 
2857  0 toggle @Override
2858    public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
2859  0 return materialize(instrumentedType,
2860    fieldRegistry,
2861    methodRegistry,
2862    new TypeAttributeAppender.Compound(this.typeAttributeAppender, typeAttributeAppender),
2863    asmVisitorWrapper,
2864    classFileVersion,
2865    auxiliaryTypeNamingStrategy,
2866    annotationValueFilterFactory,
2867    annotationRetention,
2868    implementationContextFactory,
2869    methodGraphCompiler,
2870    typeValidation,
2871    ignoredMethods);
2872    }
2873   
 
2874  12 toggle @Override
2875    public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
2876  12 return materialize(instrumentedType.withAnnotations(new ArrayList<AnnotationDescription>(annotations)),
2877    fieldRegistry,
2878    methodRegistry,
2879    typeAttributeAppender,
2880    asmVisitorWrapper,
2881    classFileVersion,
2882    auxiliaryTypeNamingStrategy,
2883    annotationValueFilterFactory,
2884    annotationRetention,
2885    implementationContextFactory,
2886    methodGraphCompiler,
2887    typeValidation,
2888    ignoredMethods);
2889    }
2890   
 
2891  339 toggle @Override
2892    public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
2893  339 return materialize(instrumentedType,
2894    fieldRegistry,
2895    methodRegistry,
2896    typeAttributeAppender,
2897    new AsmVisitorWrapper.Compound(this.asmVisitorWrapper, asmVisitorWrapper),
2898    classFileVersion,
2899    auxiliaryTypeNamingStrategy,
2900    annotationValueFilterFactory,
2901    annotationRetention,
2902    implementationContextFactory,
2903    methodGraphCompiler,
2904    typeValidation,
2905    ignoredMethods);
2906    }
2907   
2908    /**
2909    * Materializes the supplied state of a dynamic type builder.
2910    *
2911    * @param instrumentedType The instrumented type.
2912    * @param fieldRegistry The current field registry.
2913    * @param methodRegistry The current method registry.
2914    * @param typeAttributeAppender The type attribute appender to apply onto the instrumented type.
2915    * @param asmVisitorWrapper The ASM visitor wrapper to apply onto the class writer.
2916    * @param classFileVersion The class file version to define auxiliary types in.
2917    * @param auxiliaryTypeNamingStrategy The naming strategy for auxiliary types to apply.
2918    * @param annotationValueFilterFactory The annotation value filter factory to apply.
2919    * @param annotationRetention The annotation retention to apply.
2920    * @param implementationContextFactory The implementation context factory to apply.
2921    * @param methodGraphCompiler The method graph compiler to use.
2922    * @param typeValidation The type validation state.
2923    * @param ignoredMethods A matcher for identifying methods that should be excluded from instrumentation.
2924    * @return A type builder that represents the supplied arguments.
2925    */
2926    protected abstract Builder<U> materialize(InstrumentedType.WithFlexibleName instrumentedType,
2927    FieldRegistry fieldRegistry,
2928    MethodRegistry methodRegistry,
2929    TypeAttributeAppender typeAttributeAppender,
2930    AsmVisitorWrapper asmVisitorWrapper,
2931    ClassFileVersion classFileVersion,
2932    AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
2933    AnnotationValueFilter.Factory annotationValueFilterFactory,
2934    AnnotationRetention annotationRetention,
2935    Implementation.Context.Factory implementationContextFactory,
2936    MethodGraph.Compiler methodGraphCompiler,
2937    TypeValidation typeValidation,
2938    LatentMatcher<? super MethodDescription> ignoredMethods);
2939   
 
2940  84 toggle @Override
2941    public boolean equals(Object other) {
2942  84 if (this == other) return true;
2943  84 if (other == null || getClass() != other.getClass()) return false;
2944  84 Adapter<?> adapter = (Adapter<?>) other;
2945  84 return instrumentedType.equals(adapter.instrumentedType)
2946    && fieldRegistry.equals(adapter.fieldRegistry)
2947    && methodRegistry.equals(adapter.methodRegistry)
2948    && typeAttributeAppender.equals(adapter.typeAttributeAppender)
2949    && asmVisitorWrapper.equals(adapter.asmVisitorWrapper)
2950    && classFileVersion.equals(adapter.classFileVersion)
2951    && annotationValueFilterFactory.equals(adapter.annotationValueFilterFactory)
2952    && annotationRetention == adapter.annotationRetention
2953    && auxiliaryTypeNamingStrategy.equals(adapter.auxiliaryTypeNamingStrategy)
2954    && implementationContextFactory.equals(adapter.implementationContextFactory)
2955    && methodGraphCompiler.equals(adapter.methodGraphCompiler)
2956    && typeValidation.equals(adapter.typeValidation)
2957    && ignoredMethods.equals(adapter.ignoredMethods);
2958    }
2959   
 
2960  90 toggle @Override
2961    public int hashCode() {
2962  90 int result = instrumentedType.hashCode();
2963  90 result = 31 * result + fieldRegistry.hashCode();
2964  90 result = 31 * result + methodRegistry.hashCode();
2965  90 result = 31 * result + typeAttributeAppender.hashCode();
2966  90 result = 31 * result + asmVisitorWrapper.hashCode();
2967  90 result = 31 * result + classFileVersion.hashCode();
2968  90 result = 31 * result + annotationValueFilterFactory.hashCode();
2969  90 result = 31 * result + annotationRetention.hashCode();
2970  90 result = 31 * result + auxiliaryTypeNamingStrategy.hashCode();
2971  90 result = 31 * result + implementationContextFactory.hashCode();
2972  90 result = 31 * result + methodGraphCompiler.hashCode();
2973  90 result = 31 * result + typeValidation.hashCode();
2974  90 result = 31 * result + ignoredMethods.hashCode();
2975  90 return result;
2976    }
2977   
2978    /**
2979    * An adapter for defining a new type variable for the instrumented type.
2980    */
 
2981    protected class TypeVariableDefinitionAdapter extends TypeVariableDefinition.AbstractBase<U> {
2982   
2983    /**
2984    * The current definition of the type variable.
2985    */
2986    private final TypeVariableToken token;
2987   
2988    /**
2989    * Creates a new type variable definition adapter.
2990    *
2991    * @param token The current definition of the type variable.
2992    */
 
2993  38 toggle protected TypeVariableDefinitionAdapter(TypeVariableToken token) {
2994  38 this.token = token;
2995    }
2996   
 
2997  14 toggle @Override
2998    public TypeVariableDefinition<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
2999  14 return new TypeVariableDefinitionAdapter(new TypeVariableToken(token.getSymbol(),
3000    token.getBounds(),
3001    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
3002    }
3003   
 
3004  20 toggle @Override
3005    protected Builder<U> materialize() {
3006  20 return Adapter.this.materialize(instrumentedType.withTypeVariable(token),
3007    fieldRegistry,
3008    methodRegistry,
3009    typeAttributeAppender,
3010    asmVisitorWrapper,
3011    classFileVersion,
3012    auxiliaryTypeNamingStrategy,
3013    annotationValueFilterFactory,
3014    annotationRetention,
3015    implementationContextFactory,
3016    methodGraphCompiler,
3017    typeValidation,
3018    ignoredMethods);
3019    }
3020   
3021    /**
3022    * Returns the outer instance.
3023    *
3024    * @return The outer instance.
3025    */
 
3026  16 toggle private Builder.AbstractBase.Adapter<?> getOuter() {
3027  16 return Builder.AbstractBase.Adapter.this;
3028    }
3029   
 
3030  6 toggle @Override
3031    @SuppressWarnings("unchecked")
3032    public boolean equals(Object other) {
3033  6 return this == other || !(other == null || getClass() != other.getClass())
3034    && getOuter().equals(((TypeVariableDefinitionAdapter) other).getOuter())
3035    && token.equals(((TypeVariableDefinitionAdapter) other).token);
3036    }
3037   
 
3038  4 toggle @Override
3039    public int hashCode() {
3040  4 int result = getOuter().hashCode();
3041  4 result = 31 * result + token.hashCode();
3042  4 return result;
3043    }
3044   
 
3045  6 toggle @Override
3046    public String toString() {
3047  6 return "DynamicType.Builder.AbstractBase.Adapter.TypeVariableDefinitionAdapter{" +
3048    "adapter=" + getOuter() +
3049    ", token=" + token +
3050    '}';
3051    }
3052    }
3053   
3054    /**
3055    * An adapter for defining a new field.
3056    */
 
3057    protected class FieldDefinitionAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
3058   
3059    /**
3060    * The token representing the current field definition.
3061    */
3062    private final FieldDescription.Token token;
3063   
3064    /**
3065    * Creates a new field definition adapter.
3066    *
3067    * @param token The token representing the current field definition.
3068    */
 
3069  577 toggle protected FieldDefinitionAdapter(FieldDescription.Token token) {
3070  577 this(FieldAttributeAppender.ForInstrumentedField.INSTANCE, FieldTransformer.NoOp.INSTANCE, FieldDescription.NO_DEFAULT_VALUE, token);
3071    }
3072   
3073    /**
3074    * Creates a new field definition adapter.
3075    *
3076    * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
3077    * @param fieldTransformer The field transformer to apply.
3078    * @param defaultValue The field's default value or {@code null} if no value is to be defined.
3079    * @param token The token representing the current field definition.
3080    */
 
3081  625 toggle protected FieldDefinitionAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
3082    FieldTransformer fieldTransformer,
3083    Object defaultValue,
3084    FieldDescription.Token token) {
3085  625 super(fieldAttributeAppenderFactory, fieldTransformer, defaultValue);
3086  625 this.token = token;
3087    }
3088   
 
3089  2 toggle @Override
3090    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
3091  2 return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, fieldTransformer, defaultValue, new FieldDescription.Token(token.getName(),
3092    token.getModifiers(),
3093    token.getType(),
3094    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
3095    }
3096   
 
3097  572 toggle @Override
3098    protected Builder<U> materialize() {
3099  572 return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withField(token),
3100    fieldRegistry.prepend(new LatentMatcher.ForFieldToken(token), fieldAttributeAppenderFactory, defaultValue, fieldTransformer),
3101    methodRegistry,
3102    typeAttributeAppender,
3103    asmVisitorWrapper,
3104    classFileVersion,
3105    auxiliaryTypeNamingStrategy,
3106    annotationValueFilterFactory,
3107    annotationRetention,
3108    implementationContextFactory,
3109    methodGraphCompiler,
3110    typeValidation,
3111    ignoredMethods);
3112    }
3113   
 
3114  39 toggle @Override
3115    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
3116    FieldTransformer fieldTransformer,
3117    Object defaultValue) {
3118  39 return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, fieldTransformer, defaultValue, token);
3119    }
3120   
3121    /**
3122    * Returns the outer instance.
3123    *
3124    * @return The outer instance.
3125    */
 
3126  39 toggle private Builder.AbstractBase.Adapter<?> getOuter() {
3127  39 return Builder.AbstractBase.Adapter.this;
3128    }
3129   
 
3130  15 toggle @Override
3131    @SuppressWarnings("unchecked")
3132    public boolean equals(Object other) {
3133  15 return this == other || !(other == null || getClass() != other.getClass())
3134    && super.equals(other)
3135    && getOuter().equals(((FieldDefinitionAdapter) other).getOuter())
3136    && token.equals(((FieldDefinitionAdapter) other).token);
3137    }
3138   
 
3139  11 toggle @Override
3140    public int hashCode() {
3141  11 int result = super.hashCode();
3142  11 result = 31 * result + getOuter().hashCode();
3143  11 result = 31 * result + token.hashCode();
3144  11 return result;
3145    }
3146   
 
3147  16 toggle @Override
3148    public String toString() {
3149  16 return "DynamicType.Builder.AbstractBase.Adapter.FieldDefinitionAdapter{" +
3150    "adapter=" + getOuter() +
3151    ", fieldAttributeAppenderFactory=" + fieldAttributeAppenderFactory +
3152    ", fieldTransformer=" + fieldTransformer +
3153    ", defaultValue=" + defaultValue +
3154    ", token=" + token +
3155    '}';
3156    }
3157    }
3158   
3159    /**
3160    * An adapter for matching an existing field.
3161    */
 
3162    protected class FieldMatchAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
3163   
3164    /**
3165    * The matcher for any fields to apply this matcher to.
3166    */
3167    private final LatentMatcher<? super FieldDescription> matcher;
3168   
3169    /**
3170    * Creates a new field match adapter.
3171    *
3172    * @param matcher The matcher for any fields to apply this matcher to.
3173    */
 
3174  13 toggle protected FieldMatchAdapter(LatentMatcher<? super FieldDescription> matcher) {
3175  13 this(FieldAttributeAppender.NoOp.INSTANCE, FieldTransformer.NoOp.INSTANCE, FieldDescription.NO_DEFAULT_VALUE, matcher);
3176    }
3177   
3178    /**
3179    * Creates a new field match adapter.
3180    *
3181    * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
3182    * @param fieldTransformer The field transformer to apply.
3183    * @param defaultValue The field's default value or {@code null} if no value is to be defined.
3184    * @param matcher The matcher for any fields to apply this matcher to.
3185    */
 
3186  29 toggle protected FieldMatchAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
3187    FieldTransformer fieldTransformer,
3188    Object defaultValue,
3189    LatentMatcher<? super FieldDescription> matcher) {
3190  29 super(fieldAttributeAppenderFactory, fieldTransformer, defaultValue);
3191  29 this.matcher = matcher;
3192    }
3193   
 
3194  4 toggle @Override
3195    public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
3196  4 return attribute(new FieldAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
3197    }
3198   
 
3199  9 toggle @Override
3200    protected Builder<U> materialize() {
3201  9 return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
3202    fieldRegistry.prepend(matcher, fieldAttributeAppenderFactory, defaultValue, fieldTransformer),
3203    methodRegistry,
3204    typeAttributeAppender,
3205    asmVisitorWrapper,
3206    classFileVersion,
3207    auxiliaryTypeNamingStrategy,
3208    annotationValueFilterFactory,
3209    annotationRetention,
3210    implementationContextFactory,
3211    methodGraphCompiler,
3212    typeValidation,
3213    ignoredMethods);
3214    }
3215   
 
3216  9 toggle @Override
3217    protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory, FieldTransformer fieldTransformer, Object defaultValue) {
3218  9 return new FieldMatchAdapter(fieldAttributeAppenderFactory, fieldTransformer, defaultValue, matcher);
3219    }
3220   
3221    /**
3222    * Returns the outer instance.
3223    *
3224    * @return The outer instance.
3225    */
 
3226  39 toggle private Builder.AbstractBase.Adapter<?> getOuter() {
3227  39 return Builder.AbstractBase.Adapter.this;
3228    }
3229   
 
3230  15 toggle @Override
3231    @SuppressWarnings("unchecked")
3232    public boolean equals(Object other) {
3233  15 return this == other || !(other == null || getClass() != other.getClass())
3234    && super.equals(other)
3235    && getOuter().equals(((FieldMatchAdapter) other).getOuter())
3236    && matcher.equals(((FieldMatchAdapter) other).matcher);
3237    }
3238   
 
3239  11 toggle @Override
3240    public int hashCode() {
3241  11 int result = super.hashCode();
3242  11 result = 31 * result + getOuter().hashCode();
3243  11 result = 31 * result + matcher.hashCode();
3244  11 return result;
3245    }
3246   
 
3247  16 toggle @Override
3248    public String toString() {
3249  16 return "DynamicType.Builder.AbstractBase.Adapter.FieldMatchAdapter{" +
3250    "adapter=" + getOuter() +
3251    ", fieldAttributeAppenderFactory=" + fieldAttributeAppenderFactory +
3252    ", fieldTransformer=" + fieldTransformer +
3253    ", defaultValue=" + defaultValue +
3254    ", matcher=" + matcher +
3255    '}';
3256    }
3257    }
3258   
3259    /**
3260    * An adapter for defining a new method.
3261    */
 
3262    protected class MethodDefinitionAdapter extends MethodDefinition.ParameterDefinition.Initial.AbstractBase<U> {
3263   
3264    /**
3265    * A token representing the currently defined method.
3266    */
3267    private final MethodDescription.Token token;
3268   
3269    /**
3270    * Creates a new method definition adapter.
3271    *
3272    * @param token A token representing the currently defined method.
3273    */
 
3274  1025 toggle protected MethodDefinitionAdapter(MethodDescription.Token token) {
3275  1025 this.token = token;
3276    }
3277   
 
3278  6 toggle @Override
3279    public MethodDefinition.ParameterDefinition.Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers) {
3280  6 return new ParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType(), name, modifiers));
3281    }
3282   
 
3283  546 toggle @Override
3284    public Simple.Annotatable<U> withParameter(TypeDefinition type) {
3285  546 return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType()));
3286    }
3287   
 
3288  18 toggle @Override
3289    public MethodDefinition.ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types) {
3290  18 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
3291    token.getModifiers(),
3292    token.getTypeVariableTokens(),
3293    token.getReturnType(),
3294    token.getParameterTokens(),
3295    CompoundList.of(token.getExceptionTypes(), new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(types))),
3296    token.getAnnotations(),
3297    token.getDefaultValue(),
3298    token.getReceiverType()));
3299    }
3300   
 
3301  18 toggle @Override
3302    public MethodDefinition.TypeVariableDefinition.Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3303  18 return new TypeVariableAnnotationAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
3304    }
3305   
 
3306  357 toggle @Override
3307    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
3308  357 return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
3309    }
3310   
 
3311  33 toggle @Override
3312    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
3313  33 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
3314    ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers()),
3315    token.getTypeVariableTokens(),
3316    token.getReturnType(),
3317    token.getParameterTokens(),
3318    token.getExceptionTypes(),
3319    token.getAnnotations(),
3320    token.getDefaultValue(),
3321    token.getReceiverType())).materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
3322    }
3323   
 
3324  4 toggle @Override
3325    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(Object value) {
3326  4 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
3327    ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers()),
3328    token.getTypeVariableTokens(),
3329    token.getReturnType(),
3330    token.getParameterTokens(),
3331    token.getExceptionTypes(),
3332    token.getAnnotations(),
3333    value,
3334    token.getReceiverType())).materialize(MethodRegistry.Handler.ForAnnotationValue.of(value));
3335    }
3336   
3337    /**
3338    * Materializes the given handler as the implementation.
3339    *
3340    * @param handler The handler for implementing the method.
3341    * @return A method definition for the given handler.
3342    */
 
3343  394 toggle private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
3344  394 return new AnnotationAdapter(handler);
3345    }
3346   
3347    /**
3348    * Returns the outer instance.
3349    *
3350    * @return The outer instance.
3351    */
 
3352  16 toggle private Adapter<?> getOuter() {
3353  16 return Adapter.this;
3354    }
3355   
 
3356  6 toggle @Override
3357    @SuppressWarnings("unchecked")
3358    public boolean equals(Object other) {
3359  6 return this == other || !(other == null || getClass() != other.getClass())
3360    && token.equals(((MethodDefinitionAdapter) other).token)
3361    && getOuter().equals(((MethodDefinitionAdapter) other).getOuter());
3362    }
3363   
 
3364  4 toggle @Override
3365    public int hashCode() {
3366  4 return 31 * getOuter().hashCode() + token.hashCode();
3367    }
3368   
 
3369  8 toggle @Override
3370    public String toString() {
3371  8 return "DynamicType.Builder.AbstractBase.Adapter.MethodDefinitionAdapter{" +
3372    "adapter=" + getOuter() +
3373    ", token=" + token +
3374    '}';
3375    }
3376   
3377    /**
3378    * An adapter for defining a new type variable for the currently defined method.
3379    */
 
3380    protected class TypeVariableAnnotationAdapter extends MethodDefinition.TypeVariableDefinition.Annotatable.AbstractBase.Adapter<U> {
3381   
3382    /**
3383    * The currently defined type variable.
3384    */
3385    private final TypeVariableToken token;
3386   
3387    /**
3388    * Creates a new type variable annotation adapter.
3389    *
3390    * @param token The currently defined type variable.
3391    */
 
3392  34 toggle protected TypeVariableAnnotationAdapter(TypeVariableToken token) {
3393  34 this.token = token;
3394    }
3395   
 
3396  18 toggle @Override
3397    protected MethodDefinition.ParameterDefinition<U> materialize() {
3398  18 return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
3399    MethodDefinitionAdapter.this.token.getModifiers(),
3400    CompoundList.of(MethodDefinitionAdapter.this.token.getTypeVariableTokens(), token),
3401    MethodDefinitionAdapter.this.token.getReturnType(),
3402    MethodDefinitionAdapter.this.token.getParameterTokens(),
3403    MethodDefinitionAdapter.this.token.getExceptionTypes(),
3404    MethodDefinitionAdapter.this.token.getAnnotations(),
3405    MethodDefinitionAdapter.this.token.getDefaultValue(),
3406    MethodDefinitionAdapter.this.token.getReceiverType()));
3407    }
3408   
 
3409  12 toggle @Override
3410    public Annotatable<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
3411  12 return new TypeVariableAnnotationAdapter(new TypeVariableToken(token.getSymbol(),
3412    token.getBounds(),
3413    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
3414    }
3415   
3416    /**
3417    * Returns the outer instance.
3418    *
3419    * @return The outer instance.
3420    */
 
3421  15 toggle private MethodDefinitionAdapter getOuter() {
3422  15 return MethodDefinitionAdapter.this;
3423    }
3424   
 
3425  6 toggle @Override
3426    @SuppressWarnings("unchecked")
3427    public boolean equals(Object other) {
3428  6 return this == other || !(other == null || getClass() != other.getClass())
3429    && token.equals(((TypeVariableAnnotationAdapter) other).token)
3430    && getOuter().equals(((TypeVariableAnnotationAdapter) other).getOuter());
3431    }
3432   
 
3433  4 toggle @Override
3434    public int hashCode() {
3435  4 return 31 * getOuter().hashCode() + token.hashCode();
3436    }
3437   
 
3438  7 toggle @Override
3439    public String toString() {
3440  7 return "DynamicType.Builder.AbstractBase.Adapter.MethodDefinitionAdapter.TypeVariableAnnotationAdapter{" +
3441    "adapter=" + getOuter() +
3442    ", token=" + token +
3443    '}';
3444    }
3445    }
3446   
3447    /**
3448    * An annotation adapter for a parameter definition.
3449    */
 
3450    protected class ParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Annotatable.AbstractBase.Adapter<U> {
3451   
3452    /**
3453    * The token of the currently defined parameter.
3454    */
3455    private final ParameterDescription.Token token;
3456   
3457    /**
3458    * Creates a new parameter annotation adapter.
3459    *
3460    * @param token The token of the currently defined parameter.
3461    */
 
3462  10 toggle protected ParameterAnnotationAdapter(ParameterDescription.Token token) {
3463  10 this.token = token;
3464    }
3465   
 
3466  0 toggle @Override
3467    public MethodDefinition.ParameterDefinition.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
3468  0 return new ParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
3469    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
3470    token.getName(),
3471    token.getModifiers()));
3472    }
3473   
 
3474  6 toggle @Override
3475    protected MethodDefinition.ParameterDefinition<U> materialize() {
3476  6 return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
3477    MethodDefinitionAdapter.this.token.getModifiers(),
3478    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
3479    MethodDefinitionAdapter.this.token.getReturnType(),
3480    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
3481    MethodDefinitionAdapter.this.token.getExceptionTypes(),
3482    MethodDefinitionAdapter.this.token.getAnnotations(),
3483    MethodDefinitionAdapter.this.token.getDefaultValue(),
3484    MethodDefinitionAdapter.this.token.getReceiverType()));
3485    }
3486   
3487    /**
3488    * Returns the outer instance.
3489    *
3490    * @return The outer instance.
3491    */
 
3492  17 toggle private MethodDefinitionAdapter getOuter() {
3493  17 return MethodDefinitionAdapter.this;
3494    }
3495   
 
3496  6 toggle @Override
3497    @SuppressWarnings("unchecked")
3498    public boolean equals(Object other) {
3499  6 return this == other || !(other == null || getClass() != other.getClass())
3500    && token.equals(((ParameterAnnotationAdapter) other).token)
3501    && getOuter().equals(((ParameterAnnotationAdapter) other).getOuter());
3502    }
3503   
 
3504  4 toggle @Override
3505    public int hashCode() {
3506  4 return 31 * getOuter().hashCode() + token.hashCode();
3507    }
3508   
 
3509  9 toggle @Override
3510    public String toString() {
3511  9 return "DynamicType.Builder.AbstractBase.Adapter.MethodDefinitionAdapter.ParameterAnnotationAdapter{" +
3512    "adapter=" + getOuter() +
3513    ", token=" + token +
3514    '}';
3515    }
3516    }
3517   
3518    /**
3519    * An annotation adapter for a simple parameter definition.
3520    */
 
3521    protected class SimpleParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Simple.Annotatable.AbstractBase.Adapter<U> {
3522   
3523    /**
3524    * The token of the currently defined parameter.
3525    */
3526    private final ParameterDescription.Token token;
3527   
3528    /**
3529    * Creates a new simple parameter annotation adapter.
3530    *
3531    * @param token The token of the currently defined parameter.
3532    */
 
3533  550 toggle protected SimpleParameterAnnotationAdapter(ParameterDescription.Token token) {
3534  550 this.token = token;
3535    }
3536   
 
3537  0 toggle @Override
3538    public MethodDefinition.ParameterDefinition.Simple.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
3539  0 return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
3540    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
3541    token.getName(),
3542    token.getModifiers()));
3543    }
3544   
 
3545  546 toggle @Override
3546    protected MethodDefinition.ParameterDefinition.Simple<U> materialize() {
3547  546 return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
3548    MethodDefinitionAdapter.this.token.getModifiers(),
3549    MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
3550    MethodDefinitionAdapter.this.token.getReturnType(),
3551    CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
3552    MethodDefinitionAdapter.this.token.getExceptionTypes(),
3553    MethodDefinitionAdapter.this.token.getAnnotations(),
3554    MethodDefinitionAdapter.this.token.getDefaultValue(),
3555    MethodDefinitionAdapter.this.token.getReceiverType()));
3556    }
3557   
3558    /**
3559    * Returns the outer instance.
3560    *
3561    * @return The outer instance.
3562    */
 
3563  17 toggle private MethodDefinitionAdapter getOuter() {
3564  17 return MethodDefinitionAdapter.this;
3565    }
3566   
 
3567  6 toggle @Override
3568    @SuppressWarnings("unchecked")
3569    public boolean equals(Object other) {
3570  6 return this == other || !(other == null || getClass() != other.getClass())
3571    && token.equals(((SimpleParameterAnnotationAdapter) other).token)
3572    && getOuter().equals(((SimpleParameterAnnotationAdapter) other).getOuter());
3573    }
3574   
 
3575  4 toggle @Override
3576    public int hashCode() {
3577  4 return 31 * getOuter().hashCode() + token.hashCode();
3578    }
3579   
 
3580  9 toggle @Override
3581    public String toString() {
3582  9 return "DynamicType.Builder.AbstractBase.Adapter.MethodDefinitionAdapter.SimpleParameterAnnotationAdapter{" +
3583    "adapter=" + getOuter() +
3584    ", token=" + token +
3585    '}';
3586    }
3587    }
3588   
3589    /**
3590    * An annotation adapter for a method definition.
3591    */
 
3592    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
3593   
3594    /**
3595    * Creates a new annotation adapter.
3596    *
3597    * @param handler The handler that determines how a method is implemented.
3598    */
 
3599  398 toggle protected AnnotationAdapter(MethodRegistry.Handler handler) {
3600  398 this(handler, MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER, MethodTransformer.NoOp.INSTANCE);
3601    }
3602   
3603    /**
3604    * Creates a new annotation adapter.
3605    *
3606    * @param handler The handler that determines how a method is implemented.
3607    * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3608    * @param methodTransformer The method transformer to apply onto the method that is currently being implemented.
3609    */
 
3610  406 toggle protected AnnotationAdapter(MethodRegistry.Handler handler, MethodAttributeAppender.Factory methodAttributeAppenderFactory, MethodTransformer methodTransformer) {
3611  406 super(handler, methodAttributeAppenderFactory, methodTransformer);
3612    }
3613   
 
3614  1 toggle @Override
3615    public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
3616  1 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
3617    token.getModifiers(),
3618    token.getTypeVariableTokens(),
3619    token.getReturnType(),
3620    token.getParameterTokens(),
3621    token.getExceptionTypes(),
3622    token.getAnnotations(),
3623    token.getDefaultValue(),
3624    receiverType)).new AnnotationAdapter(handler, methodAttributeAppenderFactory, methodTransformer);
3625    }
3626   
 
3627  1 toggle @Override
3628    public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
3629  1 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
3630    token.getModifiers(),
3631    token.getTypeVariableTokens(),
3632    token.getReturnType(),
3633    token.getParameterTokens(),
3634    token.getExceptionTypes(),
3635    CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
3636    token.getDefaultValue(),
3637    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, methodTransformer);
3638    }
3639   
 
3640  0 toggle @Override
3641    public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
3642  0 List<ParameterDescription.Token> parameterTokens = new ArrayList<ParameterDescription.Token>(token.getParameterTokens());
3643  0 parameterTokens.add(index, new ParameterDescription.Token(token.getParameterTokens().get(index).getType(),
3644    CompoundList.of(token.getParameterTokens().get(index).getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
3645    token.getParameterTokens().get(index).getName(),
3646    token.getParameterTokens().get(index).getModifiers()));
3647  0 return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
3648    token.getModifiers(),
3649    token.getTypeVariableTokens(),
3650    token.getReturnType(),
3651    parameterTokens,
3652    token.getExceptionTypes(),
3653    token.getAnnotations(),
3654    token.getDefaultValue(),
3655    token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, methodTransformer);
3656    }
3657   
 
3658  0 toggle @Override
3659    protected MethodDefinition<U> materialize(MethodRegistry.Handler handler, MethodAttributeAppender.Factory methodAttributeAppenderFactory, MethodTransformer methodTransformer) {
3660  0 return new AnnotationAdapter(handler, methodAttributeAppenderFactory, methodTransformer);
3661    }
3662   
 
3663  394 toggle @Override
3664    protected Builder<U> materialize() {
3665  394 return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token),
3666    fieldRegistry,
3667    methodRegistry.prepend(new LatentMatcher.ForMethodToken(token),
3668    handler,
3669    methodAttributeAppenderFactory,
3670    methodTransformer),
3671    typeAttributeAppender,
3672    asmVisitorWrapper,
3673    classFileVersion,
3674    auxiliaryTypeNamingStrategy,
3675    annotationValueFilterFactory,
3676    annotationRetention,
3677    implementationContextFactory,
3678    methodGraphCompiler,
3679    typeValidation,
3680    ignoredMethods);
3681    }
3682   
3683    /**
3684    * Returns the outer instance.
3685    *
3686    * @return The outer instance.
3687    */
 
3688  22 toggle private MethodDefinitionAdapter getOuter() {
3689  22 return MethodDefinitionAdapter.this;
3690    }
3691   
 
3692  14 toggle @Override
3693    @SuppressWarnings("unchecked")
3694    public boolean equals(Object other) {
3695  14 return this == other || !(other == null || getClass() != other.getClass())
3696    && super.equals(other)
3697    && getOuter().equals(((AnnotationAdapter) other).getOuter());
3698    }
3699   
 
3700  10 toggle @Override
3701    public int hashCode() {
3702  10 return super.hashCode() + getOuter().hashCode();
3703    }
3704   
 
3705  4 toggle @Override
3706    public String toString() {
3707  4 return "DynamicType.Builder.AbstractBase.Adapter.MethodDefinitionAdapter.AnnotationAdapter{" +
3708    "adapter=" + getOuter() +
3709    ", handler=" + handler +
3710    ", methodAttributeAppenderFactory=" + methodAttributeAppenderFactory +
3711    ", methodTransformer=" + methodTransformer +
3712    '}';
3713    }
3714    }
3715    }
3716   
3717    /**
3718    * An adapter for matching an existing method.
3719    */
 
3720    protected class MethodMatchAdapter extends MethodDefinition.ImplementationDefinition.AbstractBase<U> {
3721   
3722    /**
3723    * The method matcher of this adapter.
3724    */
3725    private final LatentMatcher<? super MethodDescription> matcher;
3726   
3727    /**
3728    * Creates a new method match adapter.
3729    *
3730    * @param matcher The method matcher of this adapter.
3731    */
 
3732  907 toggle protected MethodMatchAdapter(LatentMatcher<? super MethodDescription> matcher) {
3733  907 this.matcher = matcher;
3734    }
3735   
 
3736  898 toggle @Override
3737    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
3738  898 return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
3739    }
3740   
 
3741  3 toggle @Override
3742    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
3743  3 return materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
3744    }
3745   
 
3746  2 toggle @Override
3747    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(Object value) {
3748  2 return materialize(MethodRegistry.Handler.ForAnnotationValue.of(value));
3749    }
3750   
3751    /**
3752    * Materializes the method definition with the supplied handler.
3753    *
3754    * @param handler The handler that implementes any method matched by this instances matcher.
3755    * @return A method definition where any matched method is implemented by the supplied handler.
3756    */
 
3757  903 toggle private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
3758  903 return new AnnotationAdapter(handler);
3759    }
3760   
3761    /**
3762    * Returns the outer instance.
3763    *
3764    * @return The outer instance.
3765    */
 
3766  12 toggle private Adapter<?> getOuter() {
3767  12 return Adapter.this;
3768    }
3769   
 
3770  6 toggle @Override
3771    @SuppressWarnings("unchecked")
3772    public boolean equals(Object other) {
3773  6 return this == other || !(other == null || getClass() != other.getClass())
3774    && matcher.equals(((MethodMatchAdapter) other).matcher)
3775    && getOuter().equals(((MethodMatchAdapter) other).getOuter());
3776    }
3777   
 
3778  4 toggle @Override
3779    public int hashCode() {
3780  4 return 31 * getOuter().hashCode() + matcher.hashCode();
3781    }
3782   
 
3783  4 toggle @Override
3784    public String toString() {
3785  4 return "DynamicType.Builder.AbstractBase.Adapter.MethodMatchAdapter{" +
3786    "adapter=" + getOuter() +
3787    ", matcher=" + matcher +
3788    '}';
3789    }
3790   
3791    /**
3792    * An annotation adapter for implementing annotations during a method definition.
3793    */
 
3794    protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
3795   
3796    /**
3797    * Creates a new annotation adapter.
3798    *
3799    * @param handler The handler that determines how a method is implemented.
3800    */
 
3801  907 toggle protected AnnotationAdapter(MethodRegistry.Handler handler) {
3802  907 this(handler, MethodAttributeAppender.NoOp.INSTANCE, MethodTransformer.NoOp.INSTANCE);
3803    }
3804   
3805    /**
3806    * Creates a new annotation adapter.
3807    *
3808    * @param handler The handler that determines how a method is implemented.
3809    * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3810    * @param methodTransformer The method transformer to apply onto the method that is currently being implemnted.
3811    */
 
3812  920 toggle protected AnnotationAdapter(MethodRegistry.Handler handler, MethodAttributeAppender.Factory methodAttributeAppenderFactory, MethodTransformer methodTransformer) {
3813  920 super(handler, methodAttributeAppenderFactory, methodTransformer);
3814    }
3815   
 
3816  1 toggle @Override
3817    public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
3818  1 return new AnnotationAdapter(handler,
3819    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.ForReceiverType(receiverType)),
3820    methodTransformer);
3821    }
3822   
 
3823  1 toggle @Override
3824    public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
3825  1 return new AnnotationAdapter(handler,
3826    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations))),
3827    methodTransformer);
3828    }
3829   
 
3830  0 toggle @Override
3831    public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
3832  0 return new AnnotationAdapter(handler,
3833    new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(index, new ArrayList<AnnotationDescription>(annotations))),
3834    methodTransformer);
3835    }
3836   
 
3837  5 toggle @Override
3838    protected MethodDefinition<U> materialize(MethodRegistry.Handler handler, MethodAttributeAppender.Factory methodAttributeAppenderFactory, MethodTransformer methodTransformer) {
3839  5 return new AnnotationAdapter(handler, methodAttributeAppenderFactory, methodTransformer);
3840    }
3841   
 
3842  903 toggle @Override
3843    protected Builder<U> materialize() {
3844  903 return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
3845    fieldRegistry,
3846    methodRegistry.prepend(matcher, handler, methodAttributeAppenderFactory, methodTransformer),
3847    typeAttributeAppender,
3848    asmVisitorWrapper,
3849    classFileVersion,
3850    auxiliaryTypeNamingStrategy,
3851    annotationValueFilterFactory,
3852    annotationRetention,
3853    implementationContextFactory,
3854    methodGraphCompiler,
3855    typeValidation,
3856    ignoredMethods);
3857    }
3858   
3859    /**
3860    * Returns the outer instance.
3861    *
3862    * @return The outer instance.
3863    */
 
3864  22 toggle private MethodMatchAdapter getOuter() {
3865  22 return MethodMatchAdapter.this;
3866    }
3867   
 
3868  14 toggle @Override
3869    @SuppressWarnings("unchecked")
3870    public boolean equals(Object other) {
3871  14 return this == other || !(other == null || getClass() != other.getClass())
3872    && super.equals(other)
3873    && getOuter().equals(((AnnotationAdapter) other).getOuter());
3874    }
3875   
 
3876  10 toggle @Override
3877    public int hashCode() {
3878  10 return super.hashCode() + getOuter().hashCode();
3879    }
3880   
 
3881  4 toggle @Override
3882    public String toString() {
3883  4 return "DynamicType.Builder.AbstractBase.Adapter.MethodMatchAdapter.AnnotationAdapter{" +
3884    "adapter=" + getOuter() +
3885    ", handler=" + handler +
3886    ", methodAttributeAppenderFactory=" + methodAttributeAppenderFactory +
3887    ", methodTransformer=" + methodTransformer +
3888    '}';
3889    }
3890    }
3891    }
3892   
3893    /**
3894    * An adapter for optionally matching methods defined by declared interfaces.
3895    */
 
3896    protected class OptionalMethodMatchAdapter extends Builder.AbstractBase.Delegator<U> implements MethodDefinition.ImplementationDefinition.Optional<U> {
3897   
3898    /**
3899    * The interfaces whose methods are optionally matched.
3900    */
3901    private final TypeList.Generic interfaces;
3902   
3903    /**
3904    * Creates a new optional method match adapter.
3905    *
3906    * @param interfaces The interfaces whose methods are optionally matched.
3907    */
 
3908  889 toggle protected OptionalMethodMatchAdapter(TypeList.Generic interfaces) {
3909  889 this.interfaces = interfaces;
3910    }
3911   
 
3912  885 toggle @Override
3913    protected Builder<U> materialize() {
3914  885 return Adapter.this.materialize(instrumentedType.withInterfaces(interfaces),
3915    fieldRegistry,
3916    methodRegistry,
3917    typeAttributeAppender,
3918    asmVisitorWrapper,
3919    classFileVersion,
3920    auxiliaryTypeNamingStrategy,
3921    annotationValueFilterFactory,
3922    annotationRetention,
3923    implementationContextFactory,
3924    methodGraphCompiler,
3925    typeValidation,
3926    ignoredMethods);
3927    }
3928   
 
3929  178 toggle @Override
3930    public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
3931  178 return interfaceType().intercept(implementation);
3932    }
3933   
 
3934  0 toggle @Override
3935    public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
3936  0 return interfaceType().withoutCode();
3937    }
3938   
 
3939  0 toggle @Override
3940    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(Object value) {
3941  0 return interfaceType().defaultValue(value);
3942    }
3943   
 
3944  0 toggle @Override
3945    public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(Object value, Class<?> type) {
3946  0 return interfaceType().defaultValue(value, type);
3947    }
3948   
3949    /**
3950    * Returns a matcher for the interfaces' methods.
3951    *
3952    * @return A matcher for the interfaces' methods.
3953    */
 
3954  178 toggle private MethodDefinition.ImplementationDefinition<U> interfaceType() {
3955  178 ElementMatcher.Junction<MethodDescription> elementMatcher = none();
3956  178 for (TypeDescription.Generic typeDescription : interfaces) {
3957  355 elementMatcher = elementMatcher.or(isDeclaredBy(isSubTypeOf(typeDescription.asErasure())));
3958    }
3959  178 return materialize().invokable(isDeclaredBy(isInterface()).and(elementMatcher));
3960    }
3961   
3962    /**
3963    * Returns the outer instance.
3964    *
3965    * @return The outer instance.
3966    */
 
3967  13 toggle private Builder.AbstractBase.Adapter<U> getOuter() {
3968  13 return Builder.AbstractBase.Adapter.this;
3969    }
3970   
 
3971  6 toggle @Override
3972    @SuppressWarnings("unchecked")
3973    public boolean equals(Object other) {
3974  1 if (this == other) return true;
3975  2 if (other == null || getClass() != other.getClass()) return false;
3976  3 OptionalMethodMatchAdapter that = (OptionalMethodMatchAdapter) other;
3977  3 return interfaces.equals(that.interfaces)
3978    && getOuter().equals(that.getOuter());
3979    }
3980   
 
3981  4 toggle @Override
3982    public int hashCode() {
3983  4 return 31 * getOuter().hashCode() + interfaces.hashCode();
3984    }
3985   
 
3986  5 toggle @Override
3987    public String toString() {
3988  5 return "DynamicType.Builder.AbstractBase.Adapter.OptionalMethodMatchAdapter{" +
3989    "adapter=" + getOuter() +
3990    ", interfaces=" + interfaces +
3991    '}';
3992    }
3993    }
3994    }
3995    }
3996    }
3997   
3998    /**
3999    * A dynamic type that has been loaded into the running instance of the Java virtual machine.
4000    *
4001    * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
4002    * type itself, an interface or the direct super class.
4003    */
 
4004    interface Loaded<T> extends DynamicType {
4005   
4006    /**
4007    * Returns the loaded main class.
4008    *
4009    * @return A loaded class representation of this dynamic type.
4010    */
4011    Class<? extends T> getLoaded();
4012   
4013    /**
4014    * <p>
4015    * Returns a map of all loaded auxiliary types to this dynamic type.
4016    * </p>
4017    * <p>
4018    * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
4019    * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
4020    * </p>
4021    *
4022    * @return A mapping from the fully qualified names of all auxiliary types to their loaded class representations.
4023    */
4024    Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes();
4025    }
4026   
4027    /**
4028    * A dynamic type that has not yet been loaded by a given {@link java.lang.ClassLoader}.
4029    *
4030    * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
4031    * type itself, an interface or the direct super class.
4032    */
 
4033    interface Unloaded<T> extends DynamicType {
4034   
4035    /**
4036    * Attempts to load this dynamic type including all of its auxiliary types, if any.
4037    *
4038    * @param classLoader The class loader to use for this class loading.
4039    * @param classLoadingStrategy The class loader strategy which should be used for this class loading.
4040    * @return This dynamic type in its loaded state.
4041    * @see net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default
4042    */
4043    Loaded<T> load(ClassLoader classLoader, ClassLoadingStrategy classLoadingStrategy);
4044   
4045    /**
4046    * Includes the provided dynamic types as auxiliary types of this instance.
4047    *
4048    * @param dynamicType The dynamic types to include.
4049    * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
4050    */
4051    Unloaded<T> include(DynamicType... dynamicType);
4052   
4053    /**
4054    * Includes the provided dynamic types as auxiliary types of this instance.
4055    *
4056    * @param dynamicTypes The dynamic types to include.
4057    * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
4058    */
4059    Unloaded<T> include(List<? extends DynamicType> dynamicTypes);
4060    }
4061   
4062    /**
4063    * A default implementation of a dynamic type.
4064    */
 
4065    class Default implements DynamicType {
4066   
4067    /**
4068    * The file name extension for Java class files.
4069    */
4070    private static final String CLASS_FILE_EXTENSION = ".class";
4071   
4072    /**
4073    * The default version of a jar file manifest.
4074    */
4075    private static final String MANIFEST_VERSION = "1.0";
4076   
4077    /**
4078    * The size of a writing buffer.
4079    */
4080    private static final int BUFFER_SIZE = 1024;
4081   
4082    /**
4083    * A convenience index for the beginning of an array to improve the readability of the code.
4084    */
4085    private static final int FROM_BEGINNING = 0;
4086   
4087    /**
4088    * A convenience representative of an {@link java.io.InputStream}'s end to improve the readability of the code.
4089    */
4090    private static final int END_OF_FILE = -1;
4091   
4092    /**
4093    * A suffix for temporary files.
4094    */
4095    private static final String TEMP_SUFFIX = "tmp";
4096   
4097    /**
4098    * A type description of this dynamic type.
4099    */
4100    protected final TypeDescription typeDescription;
4101   
4102    /**
4103    * The byte array representing this dynamic type.
4104    */
4105    protected final byte[] binaryRepresentation;
4106   
4107    /**
4108    * The loaded type initializer for this dynamic type.
4109    */
4110    protected final LoadedTypeInitializer loadedTypeInitializer;
4111   
4112    /**
4113    * A list of auxiliary types for this dynamic type.
4114    */
4115    protected final List<? extends DynamicType> auxiliaryTypes;
4116   
4117    /**
4118    * Creates a new dynamic type.
4119    *
4120    * @param typeDescription A description of this dynamic type.
4121    * @param binaryRepresentation A byte array containing the binary representation of this dynamic type. The array must not be modified.
4122    * @param loadedTypeInitializer The loaded type initializer of this dynamic type.
4123    * @param auxiliaryTypes The auxiliary type required for this dynamic type.
4124    */
 
4125  2344 toggle @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The received value is never modified by contract")
4126    public Default(TypeDescription typeDescription,
4127    byte[] binaryRepresentation,
4128    LoadedTypeInitializer loadedTypeInitializer,
4129    List<? extends DynamicType> auxiliaryTypes) {
4130  2344 this.typeDescription = typeDescription;
4131  2344 this.binaryRepresentation = binaryRepresentation;
4132  2344 this.loadedTypeInitializer = loadedTypeInitializer;
4133  2344 this.auxiliaryTypes = auxiliaryTypes;
4134    }
4135   
 
4136  349 toggle @Override
4137    public TypeDescription getTypeDescription() {
4138  349 return typeDescription;
4139    }
4140   
 
4141  1163 toggle @Override
4142    public Map<TypeDescription, byte[]> getAllTypes() {
4143  1163 Map<TypeDescription, byte[]> allTypes = new LinkedHashMap<TypeDescription, byte[]>();
4144  1163 allTypes.put(typeDescription, binaryRepresentation);
4145  1163 for (DynamicType auxiliaryType : auxiliaryTypes) {
4146  192 allTypes.putAll(auxiliaryType.getAllTypes());
4147    }
4148  1163 return allTypes;
4149    }
4150   
 
4151  1250 toggle @Override
4152    public Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers() {
4153  1250 Map<TypeDescription, LoadedTypeInitializer> classLoadingCallbacks = new HashMap<TypeDescription, LoadedTypeInitializer>();
4154  1250 for (DynamicType auxiliaryType : auxiliaryTypes) {
4155  217 classLoadingCallbacks.putAll(auxiliaryType.getLoadedTypeInitializers());
4156    }
4157  1250 classLoadingCallbacks.put(typeDescription, loadedTypeInitializer);
4158  1250 return classLoadingCallbacks;
4159    }
4160   
 
4161  3 toggle @Override
4162    public boolean hasAliveLoadedTypeInitializers() {
4163  3 for (LoadedTypeInitializer loadedTypeInitializer : getLoadedTypeInitializers().values()) {
4164  5 if (loadedTypeInitializer.isAlive()) {
4165  2 return true;
4166    }
4167    }
4168  1 return false;
4169    }
4170   
 
4171  159 toggle @Override
4172    @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "Return value must never be modified")
4173    public byte[] getBytes() {
4174  159 return binaryRepresentation;
4175    }
4176   
 
4177  105 toggle @Override
4178    public Map<TypeDescription, byte[]> getAuxiliaryTypes() {
4179  105 Map<TypeDescription, byte[]> auxiliaryTypes = new HashMap<TypeDescription, byte[]>();
4180  105 for (DynamicType auxiliaryType : this.auxiliaryTypes) {
4181  34 auxiliaryTypes.put(auxiliaryType.getTypeDescription(), auxiliaryType.getBytes());
4182  34 auxiliaryTypes.putAll(auxiliaryType.getAuxiliaryTypes());
4183    }
4184  105 return auxiliaryTypes;
4185    }
4186   
 
4187  1 toggle @Override
4188    public Map<TypeDescription, File> saveIn(File folder) throws IOException {
4189  1 Map<TypeDescription, File> savedFiles = new HashMap<TypeDescription, File>();
4190  1 File target = new File(folder, typeDescription.getName().replace('.', File.separatorChar) + CLASS_FILE_EXTENSION);
4191  1 if (target.getParentFile() != null) {
4192  1 if (!target.getParentFile().mkdirs()) {
4193  0 Logger.getLogger("net.bytebuddy").info("Writing file to existing folder structure: " + target.getParent());
4194    }
4195    }
4196  1 OutputStream outputStream = new FileOutputStream(target);
4197  1 try {
4198  1 outputStream.write(binaryRepresentation);
4199    } finally {
4200  1 outputStream.close();
4201    }
4202  1 savedFiles.put(typeDescription, target);
4203  1 for (DynamicType auxiliaryType : auxiliaryTypes) {
4204  1 savedFiles.putAll(auxiliaryType.saveIn(folder));
4205    }
4206  1 return savedFiles;
4207    }
4208   
 
4209  2 toggle @Override
4210    public File inject(File sourceJar, File targetJar) throws IOException {
4211  2 JarInputStream jarInputStream = new JarInputStream(new BufferedInputStream(new FileInputStream(sourceJar)));
4212  2 try {
4213  2 if (!targetJar.createNewFile()) {
4214  1 Logger.getLogger("net.bytebuddy").info("Overwriting file " + targetJar);
4215    }
4216  2 JarOutputStream jarOutputStream = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(targetJar)), jarInputStream.getManifest());
4217  2 try {
4218  2 Map<TypeDescription, byte[]> rawAuxiliaryTypes = getAuxiliaryTypes();
4219  2 Map<String, byte[]> files = new HashMap<String, byte[]>();
4220  2 for (Map.Entry<TypeDescription, byte[]> entry : rawAuxiliaryTypes.entrySet()) {
4221  2 files.put(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION, entry.getValue());
4222    }
4223  2 files.put(typeDescription.getInternalName() + CLASS_FILE_EXTENSION, binaryRepresentation);
4224  2 JarEntry jarEntry;
4225  ? while ((jarEntry = jarInputStream.getNextJarEntry()) != null) {
4226  4 jarOutputStream.putNextEntry(jarEntry);
4227  4 byte[] replacement = files.remove(jarEntry.getName());
4228  4 if (replacement == null) {
4229  2 byte[] buffer = new byte[BUFFER_SIZE];
4230  2 int index;
4231  ? while ((index = jarInputStream.read(buffer)) != END_OF_FILE) {
4232  2 jarOutputStream.write(buffer, FROM_BEGINNING, index);
4233    }
4234    } else {
4235  2 jarOutputStream.write(replacement);
4236    }
4237  4 jarInputStream.closeEntry();
4238  4 jarOutputStream.closeEntry();
4239    }
4240  2 for (Map.Entry<String, byte[]> entry : files.entrySet()) {
4241  2 jarOutputStream.putNextEntry(new JarEntry(entry.getKey()));
4242  2 jarOutputStream.write(entry.getValue());
4243  2 jarOutputStream.closeEntry();
4244    }
4245    } finally {
4246  2 jarOutputStream.close();
4247    }
4248    } finally {
4249  2 jarInputStream.close();
4250    }
4251  2 return targetJar;
4252    }
4253   
 
4254  1 toggle @Override
4255    public File inject(File jar) throws IOException {
4256  1 File temporary = inject(jar, File.createTempFile(jar.getName(), TEMP_SUFFIX));
4257  1 try {
4258  1 InputStream jarInputStream = new BufferedInputStream(new FileInputStream(temporary));
4259  1 try {
4260  1 OutputStream jarOutputStream = new BufferedOutputStream(new FileOutputStream(jar));
4261  1 try {
4262  1 byte[] buffer = new byte[BUFFER_SIZE];
4263  1 int index;
4264  ? while ((index = jarInputStream.read(buffer)) != END_OF_FILE) {
4265  1 jarOutputStream.write(buffer, FROM_BEGINNING, index);
4266    }
4267    } finally {
4268  1 jarOutputStream.close();
4269    }
4270    } finally {
4271  1 jarInputStream.close();
4272    }
4273    } finally {
4274  1 if (!temporary.delete()) {
4275  0 Logger.getLogger("net.bytebuddy").warning("Cannot delete " + temporary);
4276    }
4277    }
4278  1 return jar;
4279    }
4280   
 
4281  1 toggle @Override
4282    public File toJar(File file) throws IOException {
4283  1 Manifest manifest = new Manifest();
4284  1 manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
4285  1 return toJar(file, manifest);
4286    }
4287   
 
4288  4 toggle @Override
4289    public File toJar(File file, Manifest manifest) throws IOException {
4290  4 if (!file.createNewFile()) {
4291  2 Logger.getLogger("net.bytebuddy").info("Overwriting existing file: " + file);
4292    }
4293  4 JarOutputStream outputStream = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(file)), manifest);
4294  4 try {
4295  4 for (Map.Entry<TypeDescription, byte[]> entry : getAuxiliaryTypes().entrySet()) {
4296  2 outputStream.putNextEntry(new JarEntry(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION));
4297  2 outputStream.write(entry.getValue());
4298  2 outputStream.closeEntry();
4299    }
4300  4 outputStream.putNextEntry(new JarEntry(typeDescription.getInternalName() + CLASS_FILE_EXTENSION));
4301  4 outputStream.write(binaryRepresentation);
4302  4 outputStream.closeEntry();
4303    } finally {
4304  4 outputStream.close();
4305    }
4306  4 return file;
4307    }
4308   
 
4309  22 toggle @Override
4310    public boolean equals(Object other) {
4311  22 if (this == other)
4312  2 return true;
4313  20 if (other == null || getClass() != other.getClass())
4314  4 return false;
4315  16 Default aDefault = (Default) other;
4316  16 return auxiliaryTypes.equals(aDefault.auxiliaryTypes)
4317    && Arrays.equals(binaryRepresentation, aDefault.binaryRepresentation)
4318    && typeDescription.equals(aDefault.typeDescription)
4319    && loadedTypeInitializer.equals(aDefault.loadedTypeInitializer);
4320   
4321    }
4322   
 
4323  19 toggle @Override
4324    public int hashCode() {
4325  19 int result = typeDescription.hashCode();
4326  19 result = 31 * result + Arrays.hashCode(binaryRepresentation);
4327  19 result = 31 * result + loadedTypeInitializer.hashCode();
4328  19 result = 31 * result + auxiliaryTypes.hashCode();
4329  19 return result;
4330    }
4331   
 
4332  6 toggle @Override
4333    public String toString() {
4334  6 return "DynamicType.Default{" +
4335    "typeDescription='" + typeDescription + '\'' +
4336    ", binaryRepresentation=<" + binaryRepresentation.length + " bytes>" +
4337    ", loadedTypeInitializer=" + loadedTypeInitializer +
4338    ", auxiliaryTypes=" + auxiliaryTypes +
4339    '}';
4340    }
4341   
4342    /**
4343    * A default implementation of an unloaded dynamic type.
4344    *
4345    * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
4346    * type itself, an interface or the direct super class.
4347    */
 
4348    public static class Unloaded<T> extends Default implements DynamicType.Unloaded<T> {
4349   
4350    /**
4351    * Creates a new unloaded representation of a dynamic type.
4352    *
4353    * @param typeDescription A description of this dynamic type.
4354    * @param binaryRepresentation An array of byte of the binary representation of this dynamic type.
4355    * @param loadedTypeInitializer The type initializer of this dynamic type.
4356    * @param auxiliaryTypes The auxiliary types that are required for this dynamic type.
4357    */
 
4358  1346 toggle public Unloaded(TypeDescription typeDescription,
4359    byte[] binaryRepresentation,
4360    LoadedTypeInitializer loadedTypeInitializer,
4361    List<? extends DynamicType> auxiliaryTypes) {
4362  1346 super(typeDescription, binaryRepresentation, loadedTypeInitializer, auxiliaryTypes);
4363    }
4364   
 
4365  972 toggle @Override
4366    public DynamicType.Loaded<T> load(ClassLoader classLoader, ClassLoadingStrategy classLoadingStrategy) {
4367  972 return new Default.Loaded<T>(typeDescription,
4368    binaryRepresentation,
4369    loadedTypeInitializer,
4370    auxiliaryTypes,
4371    initialize(classLoadingStrategy.load(classLoader, getAllTypes())));
4372    }
4373   
4374    /**
4375    * Runs all loaded type initializers for all loaded classes.
4376    *
4377    * @param uninitialized The uninitialized loaded classes mapped by their type description.
4378    * @return A new hash map that contains the same classes as those given.
4379    */
 
4380  969 toggle private Map<TypeDescription, Class<?>> initialize(Map<TypeDescription, Class<?>> uninitialized) {
4381  969 Map<TypeDescription, LoadedTypeInitializer> typeInitializers = getLoadedTypeInitializers();
4382  969 for (Map.Entry<TypeDescription, Class<?>> entry : uninitialized.entrySet()) {
4383  1160 typeInitializers.get(entry.getKey()).onLoad(entry.getValue());
4384    }
4385  969 return new HashMap<TypeDescription, Class<?>>(uninitialized);
4386    }
4387   
 
4388  2 toggle @Override
4389    public DynamicType.Unloaded<T> include(DynamicType... dynamicType) {
4390  2 return include(Arrays.asList(dynamicType));
4391    }
4392   
 
4393  2 toggle @Override
4394    public DynamicType.Unloaded<T> include(List<? extends DynamicType> dynamicType) {
4395  2 return new Default.Unloaded<T>(typeDescription, binaryRepresentation, loadedTypeInitializer, CompoundList.of(auxiliaryTypes, dynamicType));
4396    }
4397   
 
4398  2 toggle @Override
4399    public String toString() {
4400  2 return "DynamicType.Default.Unloaded{" +
4401    "typeDescription='" + typeDescription + '\'' +
4402    ", binaryRepresentation=<" + binaryRepresentation.length + " bytes>" +
4403    ", typeInitializer=" + loadedTypeInitializer +
4404    ", auxiliaryTypes=" + auxiliaryTypes +
4405    '}';
4406    }
4407    }
4408   
4409    /**
4410    * A default implementation of a loaded dynamic type.
4411    *
4412    * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
4413    * type itself, an interface or the direct super class.
4414    */
 
4415    protected static class Loaded<T> extends Default implements DynamicType.Loaded<T> {
4416   
4417    /**
4418    * The loaded types for the given loaded dynamic type.
4419    */
4420    private final Map<TypeDescription, Class<?>> loadedTypes;
4421   
4422    /**
4423    * Creates a new representation of a loaded dynamic type.
4424    *
4425    * @param typeDescription A description of this dynamic type.
4426    * @param typeByte An array of byte of the binary representation of this dynamic type.
4427    * @param loadedTypeInitializer The type initializer of this dynamic type.
4428    * @param auxiliaryTypes The auxiliary types that are required for this dynamic type.
4429    * @param loadedTypes A map of loaded types for this dynamic type and all its auxiliary types.
4430    */
 
4431  978 toggle protected Loaded(TypeDescription typeDescription,
4432    byte[] typeByte,
4433    LoadedTypeInitializer loadedTypeInitializer,
4434    List<? extends DynamicType> auxiliaryTypes,
4435    Map<TypeDescription, Class<?>> loadedTypes) {
4436  978 super(typeDescription, typeByte, loadedTypeInitializer, auxiliaryTypes);
4437  978 this.loadedTypes = loadedTypes;
4438    }
4439   
 
4440  1729 toggle @Override
4441    @SuppressWarnings("unchecked")
4442    public Class<? extends T> getLoaded() {
4443  1729 return (Class<? extends T>) loadedTypes.get(typeDescription);
4444    }
4445   
 
4446  239 toggle @Override
4447    public Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes() {
4448  239 Map<TypeDescription, Class<?>> loadedAuxiliaryTypes = new HashMap<TypeDescription, Class<?>>(
4449    loadedTypes);
4450  239 loadedAuxiliaryTypes.remove(typeDescription);
4451  239 return loadedAuxiliaryTypes;
4452    }
4453   
 
4454  9 toggle @Override
4455    public boolean equals(Object other) {
4456  9 return this == other || !(other == null || getClass() != other.getClass())
4457    && super.equals(other) && loadedTypes.equals(((Default.Loaded) other).loadedTypes);
4458    }
4459   
 
4460  7 toggle @Override
4461    public int hashCode() {
4462  7 return 31 * super.hashCode() + loadedTypes.hashCode();
4463    }
4464   
 
4465  4 toggle @Override
4466    public String toString() {
4467  4 return "DynamicType.Default.Loaded{" +
4468    "typeDescription='" + typeDescription + '\'' +
4469    ", binaryRepresentation=<" + binaryRepresentation.length + " bytes>" +
4470    ", typeInitializer=" + loadedTypeInitializer +
4471    ", auxiliaryTypes=" + auxiliaryTypes +
4472    ", loadedTypes=" + loadedTypes +
4473    '}';
4474    }
4475    }
4476    }
4477    }